diff --git a/buildbot-config/platforms.py b/buildbot-config/platforms.py index 772d26c..97565d6 100644 --- a/buildbot-config/platforms.py +++ b/buildbot-config/platforms.py @@ -604,6 +604,28 @@ def nds(): register_platform(platform) nds() +def opendingux(): + platform = Platform("opendingux") + platform.compatibleBuilds = (builds.ScummVMBuild, ) + platform.env["CXX"] = "ccache ${CXX}" + platform.configureargs.append("--host=dingux") + platform.buildconfigureargs = { + builds.ScummVMBuild: [ "--enable-plugins", "--default-dynamic", "--enable-vkeybd", + # Our Tremor decoder is too old for use with Theora, we could have a more recent version + # but Theora is quite CPU intensive anyway + "--disable-theoradec" ], + } + platform.built_files = { + builds.ScummVMBuild: [ "scummvm", "plugins" ], + } + platform.archiveext = "tar.xz" + + platform.description = "OpenDingux" + platform.icon = 'dingux' + + register_platform(platform) +opendingux() + def openpandora(): platform = Platform("openpandora") platform.workerimage = "openpandora" diff --git a/check-versions/config.py b/check-versions/config.py index 115067c..899e62d 100644 --- a/check-versions/config.py +++ b/check-versions/config.py @@ -299,6 +299,22 @@ VERSIONS = { # Use same libsdl as Open2x toolchain ('./toolchains/open2x/packages/libsdl/build.sh', 'SDL'): 'ignore', + # OpenDingux packages (except toolchain) are set by (old) firmware + ('./toolchains/opendingux/packages/alsa-lib/build.sh', 'ALSA_LIB'): 'ignore', + ('./toolchains/opendingux/packages/flac/build.sh', 'FLAC'): 'ignore', + ('./toolchains/opendingux/packages/freetype/build.sh', 'FREETYPE'): 'ignore', + ('./toolchains/opendingux/packages/libiconv/build.sh', 'LIBICONV'): 'ignore', + ('./toolchains/opendingux/packages/libjpeg/build.sh', 'JPEG'): 'ignore', + ('./toolchains/opendingux/packages/libmad/build.sh', 'LIBMAD'): 'ignore', + ('./toolchains/opendingux/packages/libogg/build.sh', 'LIBOGG'): 'ignore', + ('./toolchains/opendingux/packages/libpng/build.sh', 'LIBPNG'): 'ignore', + ('./toolchains/opendingux/packages/libsdl/build.sh', 'SDL'): 'ignore', + ('./toolchains/opendingux/packages/libtheora/build.sh', 'LIBTHEORA'): 'ignore', + ('./toolchains/opendingux/packages/libvorbisidec/build.sh', 'LIBTREMOR'): 'ignore', + ('./toolchains/opendingux/packages/sdl-net1.2/build.sh', 'SDL_NET'): 'ignore', + ('./toolchains/opendingux/packages/zlib/build.sh', 'ZLIB'): 'ignore', + ('./toolchains/opendingux/packages/toolchain/build.sh', 'CT_NG'): crosstool_ng_check, + # OpenPandora packages (except toolchain) are set by (old) firmware ('./toolchains/openpandora/packages/alsa-lib/build.sh', 'ALSA_LIB'): 'ignore', ('./toolchains/openpandora/packages/curl/build.sh', 'CURL'): 'ignore', diff --git a/toolchains/opendingux/Dockerfile.m4 b/toolchains/opendingux/Dockerfile.m4 new file mode 100644 index 0000000..e6359af --- /dev/null +++ b/toolchains/opendingux/Dockerfile.m4 @@ -0,0 +1,97 @@ +m4_include(`paths.m4')m4_dnl +m4_include(`packages.m4')m4_dnl + +m4_dnl Include Debian base preparation steps +m4_dnl This ensures all common steps are shared by all toolchains +m4_include(`debian-toolchain-base.m4')m4_dnl + +COPY functions-platform.sh lib-helpers/ + +# Create fake links because those got deleted when installing gawk +# Using docker in an unprivileged container prevents deleting files across layers +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + bison \ + flex \ + gawk \ + gperf \ + g++ \ + help2man \ + libncurses-dev \ + libtool-bin \ + python-libxml2 \ + texinfo && \ + ln -s /nonexistent /etc/alternatives/awk.1.gz && \ + ln -s /nonexistent /etc/alternatives/nawk.1.gz && \ + rm -rf /var/lib/apt/lists/* + +ENV DINGUX_TOOLCHAIN=/opt/dingux-toolchain HOST=mipsel-unknown-linux-uclibc + +local_package(toolchain) + +ENV PREFIX=${DINGUX_TOOLCHAIN}/${HOST}/sysroot/usr + +ENV \ + def_binaries(`${DINGUX_TOOLCHAIN}/bin/${HOST}-', `ar, as, c++filt, ld, nm, objcopy, objdump, ranlib, readelf, strings, strip') \ + def_binaries(`${DINGUX_TOOLCHAIN}/bin/${HOST}-', `gcc, cpp, c++') \ + CC=${DINGUX_TOOLCHAIN}/bin/$HOST-gcc \ + def_aclocal(`${PREFIX}') \ + def_pkg_config(`${PREFIX}') \ + PATH=$PATH:${PREFIX}/bin + +# Use same version as official toolchain +local_package(zlib) + +# Use same version as official toolchain +local_package(libpng) + +# Use same version as official toolchain +local_package(libjpeg) + +# No libfaad2 in the original toolchain build ours statically +helpers_package(faad2) + +# Use same version as official toolchain +local_package(libmad) + +# Use same version as official toolchain +local_package(libogg) + +# Use same version as official toolchain +local_package(libtheora) + +# Use same version as official toolchain +local_package(libvorbisidec) + +# Use same version as official toolchain +local_package(flac) + +# No mpeg2dec in the original toolchain build ours statically +helpers_package(mpeg2dec) + +# No a52dec in the original toolchain build ours statically +helpers_package(a52dec) + +# Use same version as official toolchain +local_package(freetype) + +# No fribidi in the original toolchain build ours statically +helpers_package(fribidi) + +# Dependency of libsdl +# Use same version as official toolchain +local_package(alsa-lib) + +# Dependency of libsdl +# Use same version as official toolchain +local_package(libiconv) + +# Use same version as official toolchain +local_package(libsdl) + +# Use same version as official toolchain +local_package(sdl-net1.2) + +# TODO: openssl and curl + +# fluidsynth-lite is unlikely to be fast enough. diff --git a/toolchains/opendingux/functions-platform.sh b/toolchains/opendingux/functions-platform.sh new file mode 100644 index 0000000..bf3961b --- /dev/null +++ b/toolchains/opendingux/functions-platform.sh @@ -0,0 +1,3 @@ +do_configure_shared () { + ./configure --prefix=$PREFIX --host=$HOST "$@" +} diff --git a/toolchains/opendingux/packages/alsa-lib/build.sh b/toolchains/opendingux/packages/alsa-lib/build.sh new file mode 100755 index 0000000..24eb98e --- /dev/null +++ b/toolchains/opendingux/packages/alsa-lib/build.sh @@ -0,0 +1,34 @@ +#! /bin/sh + +# Stick with toolchain version +ALSA_LIB_VERSION=1.0.24.1 +ALSA_LIB_SHA256=a32f7c21015b6c71f9a80ff70a2b6a50e4ff4d5c77c744ff0793dea7ba7a2517 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch alsa-lib "http://www.alsa-project.org/files/pub/lib/alsa-lib-${ALSA_LIB_VERSION}.tar.bz2" \ + 'tar xjf' "sha256:${ALSA_LIB_SHA256}" + +# Enable shared objects to make binary lighter +do_configure_shared \ + --enable-static \ + --without-versioned \ + --disable-rawmidi \ + --disable-alisp \ + --disable-seq \ + --disable-old-symbols \ + --disable-python \ + --with-softfloat + +# Only build src and include +do_make -C src +do_make -C include + +do_make -C src install-exec +do_make -C include install + +do_clean_bdir diff --git a/toolchains/opendingux/packages/alsa-lib/patches/0001-fix-atomic-build.patch b/toolchains/opendingux/packages/alsa-lib/patches/0001-fix-atomic-build.patch new file mode 100644 index 0000000..a8fccd4 --- /dev/null +++ b/toolchains/opendingux/packages/alsa-lib/patches/0001-fix-atomic-build.patch @@ -0,0 +1,61 @@ +From f21f48a70f8437a671b58fcab75e54222a9eea16 Mon Sep 17 00:00:00 2001 +From: Kai Kang +Date: Thu, 15 Aug 2013 17:17:19 +0800 +Subject: [PATCH] Update iatomic.h functions definitions for mips + +Functions atomic_add(s) and atomic_sub(s) are defined with 'extern +__inline__' that may cause compile fails when cross compile for mips. +The error message looks like: + +| pcm/.libs/libpcm.a(pcm_meter.o): In function `snd_pcm_meter_update_scope': +| .../alsa-lib-1.0.27.2/src/pcm/pcm_meter.c:139: undefined reference to `atomic_sub' + +Replace the 'extern __inline__' with 'static __inline__' to fix this +issue. + +Signed-off-by: Kai Kang +Signed-off-by: Takashi Iwai +--- + include/iatomic.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/include/iatomic.h b/include/iatomic.h +index 5711fe8d..23932975 100644 +--- a/include/iatomic.h ++++ b/include/iatomic.h +@@ -720,7 +720,7 @@ typedef struct { volatile int counter; } atomic_t; + * Atomically adds @i to @v. Note that the guaranteed useful range + * of an atomic_t is only 24 bits. + */ +-extern __inline__ void atomic_add(int i, atomic_t * v) ++static __inline__ void atomic_add(int i, atomic_t * v) + { + unsigned long temp; + +@@ -744,7 +744,7 @@ extern __inline__ void atomic_add(int i, atomic_t * v) + * Atomically subtracts @i from @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +-extern __inline__ void atomic_sub(int i, atomic_t * v) ++static __inline__ void atomic_sub(int i, atomic_t * v) + { + unsigned long temp; + +@@ -763,7 +763,7 @@ extern __inline__ void atomic_sub(int i, atomic_t * v) + /* + * Same as above, but return the result value + */ +-extern __inline__ int atomic_add_return(int i, atomic_t * v) ++static __inline__ int atomic_add_return(int i, atomic_t * v) + { + unsigned long temp, result; + +@@ -784,7 +784,7 @@ extern __inline__ int atomic_add_return(int i, atomic_t * v) + return result; + } + +-extern __inline__ int atomic_sub_return(int i, atomic_t * v) ++static __inline__ int atomic_sub_return(int i, atomic_t * v) + { + unsigned long temp, result; + diff --git a/toolchains/opendingux/packages/flac/build.sh b/toolchains/opendingux/packages/flac/build.sh new file mode 100755 index 0000000..182a3b8 --- /dev/null +++ b/toolchains/opendingux/packages/flac/build.sh @@ -0,0 +1,23 @@ +#! /bin/sh + +# Stick with toolchain version +FLAC_VERSION=1.2.1 +FLAC_SHA256=9635a44bceb478bbf2ee8a785cf6986fba525afb5fad1fd4bba73cf71f2d3edf + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch flac "http://downloads.xiph.org/releases/flac/flac-${FLAC_VERSION}.tar.gz" \ + 'tar xzf' "sha256:${FLAC_SHA256}" + +autoreconf -fi -I m4 +do_configure_shared --disable-doxygen-docs --disable-xmms-plugin --disable-cpplibs --enable-ogg "$@" +do_make -C src/libFLAC +do_make -C src/libFLAC install +# No need to build includes +do_make -C include install + +do_clean_bdir diff --git a/toolchains/opendingux/packages/freetype/build.sh b/toolchains/opendingux/packages/freetype/build.sh new file mode 100755 index 0000000..11662f9 --- /dev/null +++ b/toolchains/opendingux/packages/freetype/build.sh @@ -0,0 +1,22 @@ +#! /bin/sh + +# Stick with toolchain version +FREETYPE_VERSION=2.3.12 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +# GPG key of Werner Lemberg +gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 0xC1A60EACE707FDA5 +do_http_fetch freetype "http://download.savannah.gnu.org/releases/freetype/freetype-old/freetype-${FREETYPE_VERSION}.tar.bz2" \ + 'tar xjf' "gpgurl:http://download.savannah.gnu.org/releases/freetype/freetype-old/freetype-${FREETYPE_VERSION}.tar.bz2.sig" +rm -Rf $HOME/.gnupg + +do_configure_shared +do_make +do_make install + +do_clean_bdir diff --git a/toolchains/opendingux/packages/libiconv/build.sh b/toolchains/opendingux/packages/libiconv/build.sh new file mode 100755 index 0000000..5788d22 --- /dev/null +++ b/toolchains/opendingux/packages/libiconv/build.sh @@ -0,0 +1,22 @@ +#! /bin/sh + +# Stick with toolchain version +LIBICONV_VERSION=1.12 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +# GPG key used for signing 1.12 is unknown... +do_http_fetch libiconv "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${LIBICONV_VERSION}.tar.gz" 'tar xzf' + +do_configure + +do_make + +# Only install library +do_make install-lib + +do_clean_bdir diff --git a/toolchains/opendingux/packages/libjpeg/build.sh b/toolchains/opendingux/packages/libjpeg/build.sh new file mode 100755 index 0000000..1e57031 --- /dev/null +++ b/toolchains/opendingux/packages/libjpeg/build.sh @@ -0,0 +1,24 @@ +#! /bin/sh + +# Stick with toolchain version +JPEG_VERSION=6b +JPEG_SHA256=75c3ec241e9996504fe02a9ed4d12f16b74ade713972f3db9e65ce95cd27e35d + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch jpeg "http://www.ijg.org/files/jpegsrc.v${JPEG_VERSION}.tar.gz" 'tar xzf' "sha256:${JPEG_SHA256}" + +# Override config.guess and config.sub with modern versions +cp /usr/share/misc/config.guess /usr/share/misc/config.sub . + +do_configure_shared --without-x --enable-shared --enable-static +do_make + +# Don't install binaries and doc +do_make install-lib + +do_clean_bdir diff --git a/toolchains/opendingux/packages/libjpeg/patches/jpeg-build.patch b/toolchains/opendingux/packages/libjpeg/patches/jpeg-build.patch new file mode 100644 index 0000000..9f3c5c2 --- /dev/null +++ b/toolchains/opendingux/packages/libjpeg/patches/jpeg-build.patch @@ -0,0 +1,99 @@ +- Respect options from configure (bindir/libdir/etc...) +- Grab AR from the env instead of hardcoding to 'ar' +- Fix install to respect $(DESTDIR) +- Also install jpegint.h #64254 + +--- jpeg/makefile.cfg ++++ jpeg/makefile.cfg +@@ -11,13 +11,13 @@ + # Where to install the programs and man pages. + prefix = @prefix@ + exec_prefix = @exec_prefix@ +-bindir = $(exec_prefix)/bin +-libdir = $(exec_prefix)/lib +-includedir = $(prefix)/include ++bindir = @bindir@ ++libdir = @libdir@ ++includedir = @includedir@ + binprefix = + manprefix = + manext = 1 +-mandir = $(prefix)/man/man$(manext) ++mandir = @mandir@/man$(manext) + + # The name of your C compiler: + CC= @CC@ +@@ -60,7 +60,8 @@ + # directory creation command + MKDIR= mkdir + # library (.a) file creation command +-AR= ar rc ++AR = @AR@ ++ARFLAGS = rc + # second step in .a creation (use "touch" if not needed) + AR2= @RANLIB@ + # installation program +@@ -163,7 +164,7 @@ + # without libtool: + libjpeg.a: @A2K_DEPS@ $(LIBOBJECTS) + $(RM) libjpeg.a +- $(AR) libjpeg.a $(LIBOBJECTS) ++ $(AR) $(ARFLAGS) libjpeg.a $(LIBOBJECTS) + $(AR2) libjpeg.a + + # with libtool: +@@ -191,25 +191,29 @@ + # Installation rules: + + install: cjpeg djpeg jpegtran rdjpgcom wrjpgcom @FORCE_INSTALL_LIB@ +- $(INSTALL_PROGRAM) cjpeg $(bindir)/$(binprefix)cjpeg +- $(INSTALL_PROGRAM) djpeg $(bindir)/$(binprefix)djpeg +- $(INSTALL_PROGRAM) jpegtran $(bindir)/$(binprefix)jpegtran +- $(INSTALL_PROGRAM) rdjpgcom $(bindir)/$(binprefix)rdjpgcom +- $(INSTALL_PROGRAM) wrjpgcom $(bindir)/$(binprefix)wrjpgcom +- $(INSTALL_DATA) $(srcdir)/cjpeg.1 $(mandir)/$(manprefix)cjpeg.$(manext) +- $(INSTALL_DATA) $(srcdir)/djpeg.1 $(mandir)/$(manprefix)djpeg.$(manext) +- $(INSTALL_DATA) $(srcdir)/jpegtran.1 $(mandir)/$(manprefix)jpegtran.$(manext) +- $(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(mandir)/$(manprefix)rdjpgcom.$(manext) +- $(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(mandir)/$(manprefix)wrjpgcom.$(manext) ++ mkdir -p $(DESTDIR)$(bindir) $(DESTDIR)$(mandir) ++ $(INSTALL_PROGRAM) cjpeg $(DESTDIR)$(bindir)/$(binprefix)cjpeg ++ $(INSTALL_PROGRAM) djpeg $(DESTDIR)$(bindir)/$(binprefix)djpeg ++ $(INSTALL_PROGRAM) jpegtran $(DESTDIR)$(bindir)/$(binprefix)jpegtran ++ $(INSTALL_PROGRAM) rdjpgcom $(DESTDIR)$(bindir)/$(binprefix)rdjpgcom ++ $(INSTALL_PROGRAM) wrjpgcom $(DESTDIR)$(bindir)/$(binprefix)wrjpgcom ++ $(INSTALL_DATA) $(srcdir)/cjpeg.1 $(DESTDIR)$(mandir)/$(manprefix)cjpeg.$(manext) ++ $(INSTALL_DATA) $(srcdir)/djpeg.1 $(DESTDIR)$(mandir)/$(manprefix)djpeg.$(manext) ++ $(INSTALL_DATA) $(srcdir)/jpegtran.1 $(DESTDIR)$(mandir)/$(manprefix)jpegtran.$(manext) ++ $(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(DESTDIR)$(mandir)/$(manprefix)rdjpgcom.$(manext) ++ $(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(DESTDIR)$(mandir)/$(manprefix)wrjpgcom.$(manext) + + install-lib: libjpeg.$(A) install-headers +- $(INSTALL_LIB) libjpeg.$(A) $(libdir)/$(binprefix)libjpeg.$(A) ++ mkdir -p $(DESTDIR)$(libdir) ++ $(INSTALL_LIB) libjpeg.$(A) $(DESTDIR)$(libdir)/$(binprefix)libjpeg.$(A) + + install-headers: jconfig.h +- $(INSTALL_DATA) jconfig.h $(includedir)/jconfig.h +- $(INSTALL_DATA) $(srcdir)/jpeglib.h $(includedir)/jpeglib.h +- $(INSTALL_DATA) $(srcdir)/jmorecfg.h $(includedir)/jmorecfg.h +- $(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h ++ mkdir -p $(DESTDIR)$(includedir) ++ $(INSTALL_DATA) jconfig.h $(DESTDIR)$(includedir)/jconfig.h ++ $(INSTALL_DATA) $(srcdir)/jpegint.h $(DESTDIR)$(includedir)/jpegint.h ++ $(INSTALL_DATA) $(srcdir)/jpeglib.h $(DESTDIR)$(includedir)/jpeglib.h ++ $(INSTALL_DATA) $(srcdir)/jmorecfg.h $(DESTDIR)$(includedir)/jmorecfg.h ++ $(INSTALL_DATA) $(srcdir)/jerror.h $(DESTDIR)$(includedir)/jerror.h + + clean: + $(RM) *.o *.lo libjpeg.a libjpeg.la +--- jpeg/configure ++++ jpeg/configure +@@ -1777,6 +1777,7 @@ + s%@CPP@%$CPP%g + s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g + s%@INSTALL_DATA@%$INSTALL_DATA%g ++s%@AR@%${AR-ar}%g + s%@RANLIB@%$RANLIB%g + s%@LIBTOOL@%$LIBTOOL%g + s%@O@%$O%g diff --git a/toolchains/opendingux/packages/libjpeg/patches/jpeg-libtool.patch b/toolchains/opendingux/packages/libjpeg/patches/jpeg-libtool.patch new file mode 100644 index 0000000..676e2c3 --- /dev/null +++ b/toolchains/opendingux/packages/libjpeg/patches/jpeg-libtool.patch @@ -0,0 +1,66 @@ +--- jpeg/configure ++++ jpeg/configure +@@ -1559,7 +1559,7 @@ + if test "x$LTSTATIC" = xno; then + disable_static="--disable-static" + fi +- $srcdir/ltconfig $disable_shared $disable_static $srcdir/ltmain.sh ++ $srcdir/ltconfig $disable_shared $disable_static $srcdir/ltmain.sh $host + fi + + # Select memory manager depending on user input. +--- jpeg/ltconfig ++++ jpeg/ltconfig +@@ -299,6 +299,7 @@ + # Transform linux* to *-*-linux-gnu*, to support old configure scripts. + case "$host_os" in + linux-gnu*) ;; ++linux-uclibc*) ;; + linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` + esac + +@@ -553,7 +553,9 @@ + # On HP-UX, both CC and GCC only warn that PIC is supported... then they + # create non-PIC objects. So, if there were any warnings, we assume that + # PIC is not supported. ++ # Make sure we only test warnings on HP-UX (pic_flag == +Z) or we can ++ # easily break Linux builds http://bugs.gentoo.org/70947 +- if test -s conftest.err; then ++ if test -s conftest.err -a "$pic_flag" = "+Z"; then + echo "$ac_t"no 1>&6 + can_build_shared=no + pic_flag= +@@ -1210,7 +1210,6 @@ + else + # Only the GNU ld.so supports shared libraries on MkLinux. + case "$host_cpu" in +- powerpc*) dynamic_linker=no ;; + *) dynamic_linker='Linux ld.so' ;; + esac + fi +@@ -1259,6 +1260,25 @@ + fi + ;; + ++linux-uclibc*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so' ++ soname_spec='${libname}${release}.so.$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ deplibs_check_method=pass_all ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ # Note: copied from linux-gnu, and may not be appropriate. ++ hardcode_into_libs=yes ++ # Assume using the uClibc dynamic linker. ++ dynamic_linker="uClibc ld.so" ++ ;; ++ + netbsd* | openbsd*) + version_type=sunos + library_names_spec='${libname}${release}.so.$versuffix' diff --git a/toolchains/opendingux/packages/libmad/build.sh b/toolchains/opendingux/packages/libmad/build.sh new file mode 100755 index 0000000..b1b1d20 --- /dev/null +++ b/toolchains/opendingux/packages/libmad/build.sh @@ -0,0 +1,22 @@ +#! /bin/sh + +# Stick with toolchain version +LIBMAD_VERSION=0.15.1b +LIBMAD_SHA256=bbfac3ed6bfbc2823d3775ebb931087371e142bb0e9bb1bee51a76a6e0078690 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch libmad "http://download.sourceforge.net/project/mad/libmad/${LIBMAD_VERSION}/libmad-${LIBMAD_VERSION}.tar.gz" \ + 'tar xzf' "sha256:${LIBMAD_SHA256}" + +touch NEWS AUTHORS ChangeLog +autoreconf -fi +do_configure_shared --disable-debugging --enable-speed +do_make +do_make install + +do_clean_bdir diff --git a/toolchains/opendingux/packages/libmad/patches/libmad-0.15.1b-mips-h-constraint-removal.patch b/toolchains/opendingux/packages/libmad/patches/libmad-0.15.1b-mips-h-constraint-removal.patch new file mode 100644 index 0000000..0958587 --- /dev/null +++ b/toolchains/opendingux/packages/libmad/patches/libmad-0.15.1b-mips-h-constraint-removal.patch @@ -0,0 +1,72 @@ +http://patchwork.openembedded.org/patch/921/ + +diff -ur libmad-0.15.1b-orig/fixed.h libmad-0.15.1b/fixed.h +--- libmad-0.15.1b-orig/fixed.h 2004-02-17 12:32:03.000000000 +1030 ++++ libmad-0.15.1b/fixed.h 2009-08-05 10:46:30.000000000 +0930 +@@ -299,6 +299,23 @@ + + # elif defined(FPM_MIPS) + ++/* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */ ++#if defined (__GNUC__) && defined (__GNUC_MINOR__) ++#define __GNUC_PREREQ(maj, min) \ ++ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) ++#else ++#define __GNUC_PREREQ(maj, min) 0 ++#endif ++ ++#if __GNUC_PREREQ(4,4) ++ typedef unsigned int u64_di_t __attribute__ ((mode (DI))); ++# define MAD_F_MLX(hi, lo, x, y) \ ++ do { \ ++ u64_di_t __ll = (u64_di_t) (x) * (y); \ ++ hi = __ll >> 32; \ ++ lo = __ll; \ ++ } while (0) ++#else + /* + * This MIPS version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). +@@ -328,6 +345,7 @@ + : "%r" ((x) >> 12), "r" ((y) >> 16)) + # define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) + # endif ++#endif /* __GNU_PREREQ(4,4) */ + + # if defined(OPT_SPEED) + # define mad_f_scale64(hi, lo) \ +diff -ur libmad-0.15.1b-orig/mad.h libmad-0.15.1b/mad.h +--- libmad-0.15.1b-orig/mad.h 2004-02-17 13:25:44.000000000 +1030 ++++ libmad-0.15.1b/mad.h 2009-08-05 10:42:40.000000000 +0930 +@@ -344,6 +344,23 @@ + + # elif defined(FPM_MIPS) + ++/* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */ ++#if defined (__GNUC__) && defined (__GNUC_MINOR__) ++#define __GNUC_PREREQ(maj, min) \ ++ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) ++#else ++#define __GNUC_PREREQ(maj, min) 0 ++#endif ++ ++#if __GNUC_PREREQ(4,4) ++ typedef unsigned int u64_di_t __attribute__ ((mode (DI))); ++# define MAD_F_MLX(hi, lo, x, y) \ ++ do { \ ++ u64_di_t __ll = (u64_di_t) (x) * (y); \ ++ hi = __ll >> 32; \ ++ lo = __ll; \ ++ } while (0) ++#else + /* + * This MIPS version is fast and accurate; the disposition of the least + * significant bit depends on OPT_ACCURACY via mad_f_scale64(). +@@ -373,6 +390,7 @@ + : "%r" ((x) >> 12), "r" ((y) >> 16)) + # define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) + # endif ++#endif /* __GNU_PREREQ(4,4) */ + + # if defined(OPT_SPEED) + # define mad_f_scale64(hi, lo) \ diff --git a/toolchains/opendingux/packages/libmad/patches/libmad-0.15.1b-remove-deprecated-cflags.patch b/toolchains/opendingux/packages/libmad/patches/libmad-0.15.1b-remove-deprecated-cflags.patch new file mode 100644 index 0000000..e504083 --- /dev/null +++ b/toolchains/opendingux/packages/libmad/patches/libmad-0.15.1b-remove-deprecated-cflags.patch @@ -0,0 +1,33 @@ +libmad: remove deprecated cflags (-fforce-mem) + +fforce-mem has long been deprecated, and is completely removed from +gcc 4.3.x on. +--- + configure | 1 - + configure.ac | 1 - + 2 files changed, 2 deletions(-) + +Index: libmad-0.15.1b/configure.ac +=================================================================== +--- libmad-0.15.1b.orig/configure.ac ++++ libmad-0.15.1b/configure.ac +@@ -140,7 +140,6 @@ + case "$optimize" in + -O|"-O "*) + optimize="-O" +- optimize="$optimize -fforce-mem" + optimize="$optimize -fforce-addr" + : #x optimize="$optimize -finline-functions" + : #- optimize="$optimize -fstrength-reduce" +Index: libmad-0.15.1b/configure +=================================================================== +--- libmad-0.15.1b.orig/configure ++++ libmad-0.15.1b/configure +@@ -19099,7 +19099,6 @@ + case "$optimize" in + -O|"-O "*) + optimize="-O" +- optimize="$optimize -fforce-mem" + optimize="$optimize -fforce-addr" + : #x optimize="$optimize -finline-functions" + : #- optimize="$optimize -fstrength-reduce" diff --git a/toolchains/opendingux/packages/libogg/build.sh b/toolchains/opendingux/packages/libogg/build.sh new file mode 100755 index 0000000..563ded9 --- /dev/null +++ b/toolchains/opendingux/packages/libogg/build.sh @@ -0,0 +1,24 @@ +#! /bin/sh + +# Stick with toolchain version +LIBOGG_VERSION=1.1.4 +LIBOGG_SHA256=9354c183fd88417c2860778b60b7896c9487d8f6e58b9fec3fdbf971142ce103 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch libogg "http://downloads.xiph.org/releases/ogg/libogg-${LIBOGG_VERSION}.tar.gz" \ + 'tar xzf' "sha256:${LIBOGG_SHA256}" + +# Avoid compiling and installing doc +sed -ie 's/^\(SUBDIRS.*\) doc/\1/' Makefile.am +autoreconf -fi + +do_configure_shared +do_make +do_make install + +do_clean_bdir diff --git a/toolchains/opendingux/packages/libpng/build.sh b/toolchains/opendingux/packages/libpng/build.sh new file mode 100755 index 0000000..985c231 --- /dev/null +++ b/toolchains/opendingux/packages/libpng/build.sh @@ -0,0 +1,28 @@ +#! /bin/sh + +# Stick with toolchain version +LIBPNG_VERSION=1.2.46 +LIBPNG_SHA256=a5e796e1802b2e221498bda09ff9850bc7ec9068b6788948cc2c42af213914d8 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch libpng "http://download.sourceforge.net/project/libpng/libpng12/older-releases/${LIBPNG_VERSION}/libpng-${LIBPNG_VERSION}.tar.bz2" \ + 'tar xjf' "sha256:${LIBPNG_SHA256}" + +# Enable shared objects to make binary lighter +do_configure_shared +do_make + +# Don't install man pages and binaries +do_make install-libLTLIBRARIES \ + install-binSCRIPTS \ + install-exec-hook \ + install-pkgconfigDATA \ + install-pkgincludeHEADERS \ + install-data-hook + +do_clean_bdir diff --git a/toolchains/opendingux/packages/libsdl/build.sh b/toolchains/opendingux/packages/libsdl/build.sh new file mode 100755 index 0000000..6bba38f --- /dev/null +++ b/toolchains/opendingux/packages/libsdl/build.sh @@ -0,0 +1,33 @@ +#! /bin/sh + +# Stick with toolchain version +SDL_VERSION=1.2.15 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +# GPG key of Sam Lantinga +gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 0xA7763BE6 +do_http_fetch SDL "https://www.libsdl.org/release/SDL-${SDL_VERSION}.tar.gz" 'tar xzf' \ + "gpgurl:http://www.libsdl.org/release/SDL-${SDL_VERSION}.tar.gz.sig" +rm -Rf $HOME/.gnupg + +./autogen.sh + +# The test fails because of cross-compilation +# DOn't know why but linuxev is disabled on official toolchain, force it here +export ac_cv_func_memcmp_working=yes +do_configure_shared \ + --enable-rpath=no \ + --enable-video-fbcon=yes \ + --enable-video-x11=no + +do_make + +# No man pages +do_make install-bin install-hdrs install-lib install-data + +do_clean_bdir diff --git a/toolchains/opendingux/packages/libsdl/patches/sdl-fbcon-waitforvsync.patch b/toolchains/opendingux/packages/libsdl/patches/sdl-fbcon-waitforvsync.patch new file mode 100644 index 0000000..eb7538a --- /dev/null +++ b/toolchains/opendingux/packages/libsdl/patches/sdl-fbcon-waitforvsync.patch @@ -0,0 +1,22 @@ +--- SDL-1.2.15.org/src/video/fbcon/SDL_fbvideo.c 2012-01-19 07:30:06.000000000 +0100 ++++ SDL-1.2.15/src/video/fbcon/SDL_fbvideo.c 2012-02-04 23:34:04.000000000 +0100 +@@ -34,6 +34,7 @@ + #include /* For definition of PAGE_SIZE */ + #endif + ++#include + #include + + #include "SDL_video.h" +@@ -1409,8 +1410,9 @@ + + static void FB_WaitVBL(_THIS) + { +-#ifdef FBIOWAITRETRACE /* Heheh, this didn't make it into the main kernel */ +- ioctl(console_fd, FBIOWAITRETRACE, 0); ++#ifdef FBIO_WAITFORVSYNC ++ unsigned int screen = 0; ++ ioctl(console_fd, FBIO_WAITFORVSYNC, &screen); + #endif + return; + } diff --git a/toolchains/opendingux/packages/libtheora/build.sh b/toolchains/opendingux/packages/libtheora/build.sh new file mode 100755 index 0000000..2dd036f --- /dev/null +++ b/toolchains/opendingux/packages/libtheora/build.sh @@ -0,0 +1,29 @@ +#! /bin/sh + +# Stick with toolchain version +LIBTHEORA_VERSION=1.0 +LIBTHEORA_SHA256=3ae9df56e8fc75ffe26e63a13cae2ce79d079416175fb0baffe0e2de8dc91a6d + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch libtheora "http://downloads.xiph.org/releases/theora/libtheora-${LIBTHEORA_VERSION}.tar.bz2" \ + 'tar xjf' "sha256:${LIBTHEORA_SHA256}" + +# Avoid compiling and installing doc +sed -ie 's/^\(SUBDIRS.*\) doc/\1/' Makefile.am +autoreconf -fi -I m4 + +do_configure_shared \ + --disable-oggtest \ + --disable-vorbistest \ + --disable-sdltest \ + --disable-examples \ + --disable-spec +do_make +do_make install + +do_clean_bdir diff --git a/toolchains/opendingux/packages/libvorbisidec/build.sh b/toolchains/opendingux/packages/libvorbisidec/build.sh new file mode 100755 index 0000000..3350aa7 --- /dev/null +++ b/toolchains/opendingux/packages/libvorbisidec/build.sh @@ -0,0 +1,20 @@ +#! /bin/sh + +# Stick with toolchain version (SVN revision 16259) +LIBTREMOR_VERSION=4ce4ec7859e7f8074341cfb00af1c207f5d24d3f + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch tremor "https://gitlab.xiph.org/xiph/tremor/-/archive/${LIBTREMOR_VERSION}/tremor-${LIBTREMOR_VERSION}.tar.gz" \ + 'tar xzf' + +autoreconf -i +do_configure_shared +do_make +do_make install + +do_clean_bdir diff --git a/toolchains/opendingux/packages/sdl-net1.2/build.sh b/toolchains/opendingux/packages/sdl-net1.2/build.sh new file mode 100755 index 0000000..43290e4 --- /dev/null +++ b/toolchains/opendingux/packages/sdl-net1.2/build.sh @@ -0,0 +1,25 @@ +#! /bin/sh + +# Stick with toolchain version +SDL_NET_VERSION=1.2.7 +SDL_NET_SHA256=2ce7c84e62ff8117b9f205758bcce68ea603e08bc9d6936ded343735b8b77c53 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch SDL_net "https://www.libsdl.org/projects/SDL_net/release/SDL_net-${SDL_NET_VERSION}.tar.gz" 'tar xzf' \ + "sha256:${SDL_NET_SHA256}" + +# Override config.guess and config.sub with modern versions +cp /usr/share/misc/config.guess /usr/share/misc/config.sub . + +do_configure_shared \ + --with-sdl-prefix="${PREFIX}" + +do_make +do_make install + +do_clean_bdir diff --git a/toolchains/opendingux/packages/toolchain/build.sh b/toolchains/opendingux/packages/toolchain/build.sh new file mode 100755 index 0000000..68cd6cd --- /dev/null +++ b/toolchains/opendingux/packages/toolchain/build.sh @@ -0,0 +1,37 @@ +#! /bin/sh + +CT_NG_VERSION=1.24.0 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +# GPG keys of Bryan Hundven and Alexey Neyman +gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 0x35B871D1 0x11D618A4 +do_http_fetch crosstool-ng "http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-${CT_NG_VERSION}.tar.bz2" 'tar xjf' \ + "gpgurl:http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-${CT_NG_VERSION}.tar.bz2.sig" +rm -Rf $HOME/.gnupg + +# Update everything as we just patched Crosstool +./bootstrap + +# Don't use do_configure as it's a pure host job +./configure --enable-local +make + +# Create tarballs directory +mkdir -p ./.tarballs + +# Update configuration +cp ${PACKAGE_DIR}/config .config +./ct-ng olddefconfig +cp ${PACKAGE_DIR}/uclibc.config uclibc.config + +./ct-ng build CT_PREFIX=${DINGUX_TOOLCHAIN} + +do_clean_bdir +# Cleanup stuff left by crosstool-ng +rm -f $HOME/.wget-hsts +rm -f /tmp/cc* diff --git a/toolchains/opendingux/packages/toolchain/config b/toolchains/opendingux/packages/toolchain/config new file mode 100644 index 0000000..5e55bb2 --- /dev/null +++ b/toolchains/opendingux/packages/toolchain/config @@ -0,0 +1,176 @@ +# +# crosstool-NG Configuration +# +CT_CONFIG_VERSION="3" + +# +# Paths and misc options +# + +# +# crosstool-NG behavior +# +# uClibc version is obsolete but it's what OpenDingux has +CT_OBSOLETE=y + +# +# Paths +# +# Define all paths +# +CT_LOCAL_TARBALLS_DIR="${CT_TOP_DIR}/.tarballs" +CT_WORK_DIR="${CT_TOP_DIR}/.build" +CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" +CT_PREFIX_DIR="${CT_PREFIX:-${CT_TOP_DIR}/toolchain}" +# Don't put toolchain R/O as we need to install libraries in it +# CT_PREFIX_DIR_RO is not set + +# +# Target options +# +# That's a MIPS 32r2 +CT_ARCH_MIPS=y +CT_ARCH_TUNE="mips32r2" + +# +# Options for mips +# + +# +# Generic target options +# +# Little endian +CT_ARCH_LE=y +# Quite simply o32 +CT_ARCH_32=y + +# +# Target optimisations +# +# Specify precise arch +CT_ARCH_ARCH="mips32r2" +# No hardfloat on the target +CT_ARCH_FLOAT_SW=y + +# +# Toolchain options +# + +# +# General toolchain options +# + +# +# Tuple completion and aliasing +# + +# +# Toolchain type +# +CT_CROSS=y + +# +# Build system +# + +# +# Misc options +# + +# +# Operating System +# +CT_KERNEL_LINUX=y + +# +# Options for linux +# +# Use 2.6.36 kernel like the one running on the target +CT_LINUX_SRC_RELEASE=y +CT_LINUX_V_2_6_36=y + +# +# Common kernel options +# + +# +# Binary utilities +# + +# +# Options for binutils +# + +# +# GNU binutils +# + +# +# C-library +# +CT_LIBC_UCLIBC=y + +# +# Options for uClibc +# +# Use same uClibc as the target to avoid static linking of it +CT_UCLIBC_USE_UCLIBC_ORG=y +CT_UCLIBC_SRC_RELEASE=y +CT_UCLIBC_V_0_9_31=y +CT_LIBC_UCLIBC_CONFIG_FILE="${CT_TOP_DIR}/uclibc.config" +# CT_LIBC_UCLIBC_LOCALES is not set +# CT_LIBC_UCLIBC_IPV6 is not set +CT_LIBC_UCLIBC_WCHAR=y +# CT_LIBC_UCLIBC_FENV is not set +# CT_LIBC_UCLIBC_RPC is not set +# CT_LIBC_UCLIBC_HAS_SSP is not set + +# +# Common C library options +# +# Use LT threads (no other choice though) +CT_THREADS_LT=y + +# +# C compiler +# +CT_CC_GCC=y + +# +# Options for gcc +# +# Don't build shared libgcc_s and libstdc++ as we are way more recent than the target compiler +CT_CC_GCC_EXTRA_CONFIG_ARRAY="--disable-shared" + +# +# Optimisation features +# +# Make the toolchain lighter +# CT_CC_GCC_USE_GRAPHITE is not set +# CT_CC_GCC_USE_LTO is not set + +# +# Settings for libraries running on target +# + +# +# Misc. obscure options. +# + +# +# Additional supported languages: +# +# Support C++ +CT_CC_LANG_CXX=y + +# +# Debug facilities +# + +# +# Companion libraries +# + +# +# Companion tools +# diff --git a/toolchains/opendingux/packages/toolchain/patches/0001-Allow-compilation-by-root.patch b/toolchains/opendingux/packages/toolchain/patches/0001-Allow-compilation-by-root.patch new file mode 100644 index 0000000..ac1d370 --- /dev/null +++ b/toolchains/opendingux/packages/toolchain/patches/0001-Allow-compilation-by-root.patch @@ -0,0 +1,36 @@ +From 18789ea9bff4cf2b653e482227167d12edcbcaa2 Mon Sep 17 00:00:00 2001 +From: Le Philousophe +Date: Sun, 28 Feb 2021 10:36:45 +0100 +Subject: [PATCH 1/3] Allow compilation by root + +--- + config/global/ct-behave.in | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/config/global/ct-behave.in b/config/global/ct-behave.in +index 42171e4d..244a2d60 100644 +--- a/config/global/ct-behave.in ++++ b/config/global/ct-behave.in +@@ -30,9 +30,8 @@ config EXPERIMENTAL + the result + + config ALLOW_BUILD_AS_ROOT +- bool ++ def_bool y + prompt "Allow building as root user (READ HELP!)" +- depends on EXPERIMENTAL + help + You normally do *not* need to be root to build a toolchain using + crosstool-NG. In fact, it is *VERY* dangerous to run as root, as +@@ -56,7 +55,7 @@ config ALLOW_BUILD_AS_ROOT + (ad libitum) + + config ALLOW_BUILD_AS_ROOT_SURE +- bool ++ def_bool y + prompt "Are you sure?" + depends on ALLOW_BUILD_AS_ROOT + +-- +2.25.1 + diff --git a/toolchains/opendingux/packages/toolchain/patches/0002-Allow-static-libstdc.patch b/toolchains/opendingux/packages/toolchain/patches/0002-Allow-static-libstdc.patch new file mode 100644 index 0000000..3a24b59 --- /dev/null +++ b/toolchains/opendingux/packages/toolchain/patches/0002-Allow-static-libstdc.patch @@ -0,0 +1,45 @@ +From cd02b6212271534cdbb6254993158eb7590e517f Mon Sep 17 00:00:00 2001 +From: Le Philousophe +Date: Sun, 28 Feb 2021 10:38:18 +0100 +Subject: [PATCH 2/3] Allow static libstdc++ + +--- + .../8.3.0/9999-allow-static-libstdc++.patch | 26 +++++++++++++++++++ + 1 file changed, 26 insertions(+) + create mode 100644 packages/gcc/8.3.0/9999-allow-static-libstdc++.patch + +diff --git a/packages/gcc/8.3.0/9999-allow-static-libstdc++.patch b/packages/gcc/8.3.0/9999-allow-static-libstdc++.patch +new file mode 100644 +index 00000000..725130fd +--- /dev/null ++++ b/packages/gcc/8.3.0/9999-allow-static-libstdc++.patch +@@ -0,0 +1,26 @@ ++--- a/libstdc++-v3/configure.ac +++++ b/libstdc++-v3/configure.ac ++@@ -121,8 +121,8 @@ if test "$enable_shared" = yes; then ++ glibcxx_compiler_shared_flag="-D_GLIBCXX_SHARED" ++ ++ else ++- glibcxx_lt_pic_flag= ++- glibcxx_compiler_pic_flag= +++ glibcxx_lt_pic_flag="-prefer-pic" +++ glibcxx_compiler_pic_flag="$lt_prog_compiler_pic_CXX" ++ glibcxx_compiler_shared_flag= ++ fi ++ AC_SUBST(glibcxx_lt_pic_flag) ++--- a/libstdc++-v3/configure +++++ b/libstdc++-v3/configure ++@@ -15025,8 +15025,8 @@ if test "$enable_shared" = yes; then ++ glibcxx_compiler_shared_flag="-D_GLIBCXX_SHARED" ++ ++ else ++- glibcxx_lt_pic_flag= ++- glibcxx_compiler_pic_flag= +++ glibcxx_lt_pic_flag="-prefer-pic" +++ glibcxx_compiler_pic_flag="$lt_prog_compiler_pic_CXX" ++ glibcxx_compiler_shared_flag= ++ fi ++ +-- +2.25.1 + diff --git a/toolchains/opendingux/packages/toolchain/patches/0003-Add-OpenDingux-support.patch b/toolchains/opendingux/packages/toolchain/patches/0003-Add-OpenDingux-support.patch new file mode 100644 index 0000000..398b135 --- /dev/null +++ b/toolchains/opendingux/packages/toolchain/patches/0003-Add-OpenDingux-support.patch @@ -0,0 +1,8067 @@ +From 5ce92692e77aa3a469996675da3db9d61fa264ae Mon Sep 17 00:00:00 2001 +From: Le Philousophe +Date: Wed, 3 Mar 2021 07:42:30 +0100 +Subject: [PATCH 3/3] Add OpenDingux support + +--- + .../uClibc/0.9.31/0002-fix-darwin-build.patch | 15 + + .../uClibc/0.9.31/0004-no-install-D.patch | 31 + + .../uClibc/0.9.31/0005-prefer-multilib.patch | 40 + + .../0.9.31/0007-make-olddefconfig.patch | 44 + + .../0.9.31/9998-fix-crtn-compilation.patch | 122 + + .../0.9.31/9999-pregen-before-install.patch | 11 + + packages/uClibc/0.9.31/chksum | 8 + + ...libc-0.9.31-dnslookup-use-after-free.patch | 36 + + ...uClibc-0.9.31-fix-error-locale-utf-8.patch | 17 + + ....9.31-fix-fcntl64-for-64-bit-targets.patch | 34 + + ...-0.9.31-more-workarounds-GCC-PR32219.patch | 40 + + .../uClibc-0.9.31-powerpc-ptrace-fix.patch | 62 + + .../0.9.31/uClibc-0.9.31-quad-routines.patch | 7393 +++++++++++++++++ + ...uClibc-0.9.31-workaround-GCC-PR32219.patch | 57 + + packages/uClibc/0.9.31/version.desc | 1 + + packages/uClibc/package.desc | 2 +- + scripts/build/libc/uClibc.sh | 1 + + 17 files changed, 7913 insertions(+), 1 deletion(-) + create mode 100644 packages/uClibc/0.9.31/0002-fix-darwin-build.patch + create mode 100644 packages/uClibc/0.9.31/0004-no-install-D.patch + create mode 100644 packages/uClibc/0.9.31/0005-prefer-multilib.patch + create mode 100644 packages/uClibc/0.9.31/0007-make-olddefconfig.patch + create mode 100644 packages/uClibc/0.9.31/9998-fix-crtn-compilation.patch + create mode 100644 packages/uClibc/0.9.31/9999-pregen-before-install.patch + create mode 100644 packages/uClibc/0.9.31/chksum + create mode 100644 packages/uClibc/0.9.31/uClibc-0.9.31-dnslookup-use-after-free.patch + create mode 100644 packages/uClibc/0.9.31/uClibc-0.9.31-fix-error-locale-utf-8.patch + create mode 100644 packages/uClibc/0.9.31/uClibc-0.9.31-fix-fcntl64-for-64-bit-targets.patch + create mode 100644 packages/uClibc/0.9.31/uClibc-0.9.31-more-workarounds-GCC-PR32219.patch + create mode 100644 packages/uClibc/0.9.31/uClibc-0.9.31-powerpc-ptrace-fix.patch + create mode 100644 packages/uClibc/0.9.31/uClibc-0.9.31-quad-routines.patch + create mode 100644 packages/uClibc/0.9.31/uClibc-0.9.31-workaround-GCC-PR32219.patch + create mode 100644 packages/uClibc/0.9.31/version.desc + +diff --git a/packages/uClibc/0.9.31/0002-fix-darwin-build.patch b/packages/uClibc/0.9.31/0002-fix-darwin-build.patch +new file mode 100644 +index 00000000..666219c7 +--- /dev/null ++++ b/packages/uClibc/0.9.31/0002-fix-darwin-build.patch +@@ -0,0 +1,15 @@ ++--- ++ extra/scripts/unifdef.c | 2 -- ++ 1 file changed, 2 deletions(-) ++ ++--- a/extra/scripts/unifdef.c +++++ b/extra/scripts/unifdef.c ++@@ -78,8 +78,6 @@ ++ #define errx(exit_code, fmt, args...) ({ warnx(fmt, ## args); exit(exit_code); }) ++ #define err(exit_code, fmt, args...) errx(exit_code, fmt ": %s", ## args, strerror(errno)) ++ ++-size_t strlcpy(char *dst, const char *src, size_t siz); ++- ++ /* types of input lines: */ ++ typedef enum { ++ LT_TRUEI, /* a true #if with ignore flag */ +diff --git a/packages/uClibc/0.9.31/0004-no-install-D.patch b/packages/uClibc/0.9.31/0004-no-install-D.patch +new file mode 100644 +index 00000000..1da2bcb4 +--- /dev/null ++++ b/packages/uClibc/0.9.31/0004-no-install-D.patch +@@ -0,0 +1,31 @@ ++--- ++ utils/Makefile.in | 15 +++++++++++---- ++ 1 file changed, 11 insertions(+), 4 deletions(-) ++ ++--- a/utils/Makefile.in +++++ b/utils/Makefile.in ++@@ -113,14 +113,21 @@ ++ install-y += utils_install ++ ++ # This installs both utils and hostutils, so doesn't depend on either. +++$(PREFIX)$(DEVEL_PREFIX)bin $(PREFIX)$(RUNTIME_PREFIX)sbin: +++ $(do_mkdir) +++ +++utils_install: $(PREFIX)$(DEVEL_PREFIX)bin +++ifeq ($(HAVE_SHARED),y) +++utils_install: $(PREFIX)$(RUNTIME_PREFIX)sbin +++endif ++ ++ utils_install: $(addsuffix $(DOTHOST), $(utils_OBJ) $(utils_LOCALE_OBJ)) ++ ifeq ($(HAVE_SHARED),y) ++- $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/ldd$(DOTHOST) $(PREFIX)$(DEVEL_PREFIX)bin/ldd ++- $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/ldconfig$(DOTHOST) $(PREFIX)$(RUNTIME_PREFIX)sbin/ldconfig +++ $(Q)$(INSTALL) -m 755 $(utils_OUT)/ldd$(DOTHOST) $(PREFIX)$(DEVEL_PREFIX)bin/ldd +++ $(Q)$(INSTALL) -m 755 $(utils_OUT)/ldconfig$(DOTHOST) $(PREFIX)$(RUNTIME_PREFIX)sbin/ldconfig ++ endif ++ ifeq ($(UCLIBC_HAS_LOCALE),y) ++- $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/iconv$(DOTHOST) $(PREFIX)$(DEVEL_PREFIX)bin/iconv +++ $(Q)$(INSTALL) -m 755 $(utils_OUT)/iconv$(DOTHOST) $(PREFIX)$(DEVEL_PREFIX)bin/iconv ++ #$(Q)$(INSTALL) -m 755 $(utils_OUT)/locale$(DOTHOST) $(PREFIX)$(DEVEL_PREFIX)bin/locale ++ endif ++ +diff --git a/packages/uClibc/0.9.31/0005-prefer-multilib.patch b/packages/uClibc/0.9.31/0005-prefer-multilib.patch +new file mode 100644 +index 00000000..41676f38 +--- /dev/null ++++ b/packages/uClibc/0.9.31/0005-prefer-multilib.patch +@@ -0,0 +1,40 @@ ++--- ++ ldso/ldso/Makefile.in | 5 +++++ ++ ldso/ldso/dl-elf.c | 13 +++++++++++++ ++ 2 files changed, 18 insertions(+) ++ ++--- a/ldso/ldso/dl-elf.c +++++ b/ldso/ldso/dl-elf.c ++@@ -283,6 +283,18 @@ ++ } ++ } ++ #endif +++ +++#ifdef LDSO_MULTILIB_DIR +++ /* If multilib directory is selected, search it before falling back to +++ standard lib directories. */ +++ _dl_if_debug_dprint("\tsearching multilib lib path list\n"); +++ tpnt1 = search_for_named_library(libname, rflags, +++ UCLIBC_RUNTIME_PREFIX LDSO_MULTILIB_DIR ":" +++ UCLIBC_RUNTIME_PREFIX "usr" LDSO_MULTILIB_DIR, +++ rpnt); +++ if (tpnt1 != NULL) +++ return tpnt1; +++#endif ++ ++ /* Look for libraries wherever the shared library loader ++ * was installed */ ++--- a/ldso/ldso/Makefile.in +++++ b/ldso/ldso/Makefile.in ++@@ -30,6 +30,11 @@ ++ ++ CFLAGS-ldso.c := -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\" $(CFLAGS-ldso) ++ +++# Search non-default multilib directories +++ifneq ($(MULTILIB_DIR),lib) +++CFLAGS-ldso.c += -DLDSO_MULTILIB_DIR=\"$(MULTILIB_DIR)\" +++endif +++ ++ ifneq ($(SUPPORT_LD_DEBUG),y) ++ LDFLAGS-$(UCLIBC_LDSO_NAME).so := $(LDFLAGS) ++ else +diff --git a/packages/uClibc/0.9.31/0007-make-olddefconfig.patch b/packages/uClibc/0.9.31/0007-make-olddefconfig.patch +new file mode 100644 +index 00000000..ceef7adc +--- /dev/null ++++ b/packages/uClibc/0.9.31/0007-make-olddefconfig.patch +@@ -0,0 +1,44 @@ ++--- ++ Makefile.in | 3 +++ ++ extra/config/conf.c | 4 +++- ++ 2 files changed, 6 insertions(+), 1 deletion(-) ++ ++--- a/extra/config/conf.c +++++ b/extra/config/conf.c ++@@ -435,6 +435,7 @@ ++ const char *name; ++ const char *configname = conf_get_configname(); ++ struct stat tmpstat; +++ int olddefconfig = 0; ++ ++ setlocale(LC_ALL, ""); ++ bindtextdomain(PACKAGE, LOCALEDIR); ++@@ -451,6 +452,7 @@ ++ break; ++ case 'd': ++ input_mode = set_default; +++ olddefconfig = 1; ++ break; ++ case 'D': ++ input_mode = set_default; ++@@ -514,7 +516,7 @@ ++ switch (input_mode) { ++ case set_default: ++ if (!defconfig_file) ++- defconfig_file = conf_get_default_confname(); +++ defconfig_file = olddefconfig ? NULL : conf_get_default_confname(); ++ if (conf_read(defconfig_file)) { ++ printf(_("***\n" ++ "*** Can't find default configuration \"%s\"!\n" ++--- a/Makefile.in +++++ b/Makefile.in ++@@ -460,6 +460,9 @@ ++ allnoconfig: $(top_builddir)extra/config/conf ++ $(Q)$(top_builddir)extra/config/conf -n extra/Configs/Config.in ++ +++olddefconfig: $(top_builddir)extra/config/conf +++ $(Q)$(top_builddir)extra/config/conf -d extra/Configs/Config.in +++ ++ defconfig: $(top_builddir)extra/config/conf ++ $(Q)$(top_builddir)extra/config/conf -d extra/Configs/Config.in \ ++ -D extra/Configs/defconfigs/$(ARCH) +diff --git a/packages/uClibc/0.9.31/9998-fix-crtn-compilation.patch b/packages/uClibc/0.9.31/9998-fix-crtn-compilation.patch +new file mode 100644 +index 00000000..46dc16c2 +--- /dev/null ++++ b/packages/uClibc/0.9.31/9998-fix-crtn-compilation.patch +@@ -0,0 +1,122 @@ ++From c97ce776368ec5d9d954fc8653f3e1c11490fc74 Mon Sep 17 00:00:00 2001 ++From: Khem Raj ++Date: Mon, 13 Jun 2011 16:30:55 -0700 ++Subject: [PATCH] ctor/dtor nptl: Fix init and fini function compilation ++ ++We need to define the rules for .S files so it ++gets the include paths some architectures like mips ++include headers ++ ++Some architectures e.g. SH have their own version ++of pt-initfini.c so look for that first before resorting ++to generic version of pt-initfini.c ++ ++Signed-off-by: Khem Raj ++--- ++ libc/sysdeps/linux/mips/crtn.S | 15 ------------ ++ libpthread/nptl/Makefile.in | 4 ++-- ++ libpthread/nptl/sysdeps/pthread/Makefile.in | 26 ++++++++++++++++----- ++ 3 files changed, 22 insertions(+), 23 deletions(-) ++ ++diff --git a/libc/sysdeps/linux/mips/crtn.S b/libc/sysdeps/linux/mips/crtn.S ++index cedd593f0..f3756a2f1 100644 ++--- a/libc/sysdeps/linux/mips/crtn.S +++++ b/libc/sysdeps/linux/mips/crtn.S ++@@ -10,7 +10,6 @@ ++ #NO_APP ++ .align 2 ++ .globl _init ++- .ent _init ++ .type _init, @function ++ #NO_APP ++ lw $31,28($sp) ++@@ -22,14 +21,12 @@ ++ .set macro ++ .set reorder ++ ++- .end _init ++ #APP ++ ++ .section .fini ++ #NO_APP ++ .align 2 ++ .globl _fini ++- .ent _fini ++ .type _fini, @function ++ #NO_APP ++ lw $31,28($sp) ++@@ -41,7 +38,6 @@ ++ .set macro ++ .set reorder ++ ++- .end _fini ++ #APP ++ ++ .ident "GCC: (GNU) 3.3.2" ++@@ -54,10 +50,8 @@ ++ ++ .section .init ++ #NO_APP ++- .align 2 ++ .align 3 ++ .globl _init ++- .ent _init ++ .type _init, @function ++ #NO_APP ++ ld $31,8($sp) ++@@ -68,16 +62,12 @@ ++ addiu $sp,$sp,16 ++ .set macro ++ .set reorder ++- ++- .end _init ++ #APP ++ ++ .section .fini ++ #NO_APP ++- .align 2 ++ .align 3 ++ .globl _fini ++- .ent _fini ++ .type _fini, @function ++ #NO_APP ++ ld $31,8($sp) ++@@ -89,7 +79,6 @@ ++ .set macro ++ .set reorder ++ ++- .end _fini ++ #APP ++ ++ .ident "GCC: (GNU) 3.4.3" ++@@ -105,7 +94,6 @@ ++ #NO_APP ++ .align 2 ++ .globl _init ++- .ent _init ++ .type _init, @function ++ #NO_APP ++ ld $31,24($sp) ++@@ -118,14 +106,12 @@ ++ .set macro ++ .set reorder ++ ++- .end _init ++ #APP ++ ++ .section .fini ++ #NO_APP ++ .align 2 ++ .globl _fini ++- .ent _fini ++ .type _fini, @function ++ #NO_APP ++ ld $31,24($sp) ++@@ -138,7 +124,6 @@ ++ .set macro ++ .set reorder ++ ++- .end _fini ++ #APP ++ ++ .ident "GCC: (GNU) 3.3.2" +diff --git a/packages/uClibc/0.9.31/9999-pregen-before-install.patch b/packages/uClibc/0.9.31/9999-pregen-before-install.patch +new file mode 100644 +index 00000000..a1c6f47d +--- /dev/null ++++ b/packages/uClibc/0.9.31/9999-pregen-before-install.patch +@@ -0,0 +1,11 @@ ++--- a/Makefile.in 2021-02-28 16:21:57.126540862 +0100 +++++ b/Makefile.in 2021-02-28 16:22:06.266488008 +0100 ++@@ -291,7 +291,7 @@ ++ $(do_mkdir) ++ endif ++ ++-install_headers: headers $(top_builddir)extra/scripts/unifdef | $(PREFIX)$(DEVEL_PREFIX)include +++install_headers: pregen $(top_builddir)extra/scripts/unifdef | $(PREFIX)$(DEVEL_PREFIX)include ++ top_builddir=$(top_builddir) \ ++ $(top_srcdir)extra/scripts/install_headers.sh include $(PREFIX)$(DEVEL_PREFIX)include ++ cd $(PREFIX)$(DEVEL_PREFIX)include && $(RM) -r $(HEADERS_RM-) +diff --git a/packages/uClibc/0.9.31/chksum b/packages/uClibc/0.9.31/chksum +new file mode 100644 +index 00000000..bf1412ac +--- /dev/null ++++ b/packages/uClibc/0.9.31/chksum +@@ -0,0 +1,8 @@ ++md5 uClibc-0.9.31.tar.xz 5a222b2112bc2b76e384a11c0304da15 ++sha1 uClibc-0.9.31.tar.xz 93fa867436db8151a76c9c1966540929ad894ad2 ++sha256 uClibc-0.9.31.tar.xz b8caab8e7ba29432344b8134d2e47bdd451bee64cd5863f6a7bb2f7b0ac8ecfb ++sha512 uClibc-0.9.31.tar.xz 08261930201e9ac6b6070951b5abc18bc028762cf7c0ca8af5f7e2c151cad120edcddd7a81d38b0950637de26a04ab0fb05cacb4eb77e68d14958b780c83b6f4 ++md5 uClibc-0.9.31.tar.bz2 52fb8a494758630c8d3ddd7f1e0daafd ++sha1 uClibc-0.9.31.tar.bz2 f25f70534594dffdb6b9008799a1532271178338 ++sha256 uClibc-0.9.31.tar.bz2 80d33549d2a5d7ddc95b10dd964fead34d568c47268bba057c4b816f1d1263fa ++sha512 uClibc-0.9.31.tar.bz2 6e4b71f0fedeabcdb20b6d08bbd70ce2dac28229431a1f3457e9218f95eb8b796b79c2663bb8fcc8de18e2ae6ae15303091db61980a9d1dc4a25393a3b6547c4 +diff --git a/packages/uClibc/0.9.31/uClibc-0.9.31-dnslookup-use-after-free.patch b/packages/uClibc/0.9.31/uClibc-0.9.31-dnslookup-use-after-free.patch +new file mode 100644 +index 00000000..9956d591 +--- /dev/null ++++ b/packages/uClibc/0.9.31/uClibc-0.9.31-dnslookup-use-after-free.patch +@@ -0,0 +1,36 @@ ++From eb1d8c8289f466ba3ad10b9a88ab2e426b8a9dc7 Mon Sep 17 00:00:00 2001 ++From: Gabor Juhos ++Date: Tue, 6 Apr 2010 09:55:19 +0200 ++Subject: [PATCH] Fix use-after-free bug in __dns_lookup ++ ++If the type of the first answer does not match with the requested type, ++then the dotted name was freed. If there are no further answers in ++the DNS reply, this pointer was used later on in the same function. ++Additionally it is passed to the caller, and caused strange ++behaviour. ++ ++Signed-off-by: Gabor Juhos ++Signed-off-by: Bernhard Reutner-Fischer ++--- ++ libc/inet/resolv.c | 4 +--- ++ 1 files changed, 1 insertions(+), 3 deletions(-) ++ ++diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c ++index 056539f..9459199 100644 ++--- a/libc/inet/resolv.c +++++ b/libc/inet/resolv.c ++@@ -1517,10 +1517,8 @@ int attribute_hidden __dns_lookup(const char *name, ++ memcpy(a, &ma, sizeof(ma)); ++ if (a->atype != T_SIG && (NULL == a->buf || (type != T_A && type != T_AAAA))) ++ break; ++- if (a->atype != type) { ++- free(a->dotted); +++ if (a->atype != type) ++ continue; ++- } ++ a->add_count = h.ancount - j - 1; ++ if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen) ++ break; ++-- ++1.7.0 ++ +diff --git a/packages/uClibc/0.9.31/uClibc-0.9.31-fix-error-locale-utf-8.patch b/packages/uClibc/0.9.31/uClibc-0.9.31-fix-error-locale-utf-8.patch +new file mode 100644 +index 00000000..1305add5 +--- /dev/null ++++ b/packages/uClibc/0.9.31/uClibc-0.9.31-fix-error-locale-utf-8.patch +@@ -0,0 +1,17 @@ ++--- ++ extra/locale/gen_wc8bit.c | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++Index: uClibc-0.9.31/extra/locale/gen_wc8bit.c ++=================================================================== ++--- uClibc-0.9.31.orig/extra/locale/gen_wc8bit.c +++++ uClibc-0.9.31/extra/locale/gen_wc8bit.c ++@@ -120,7 +120,7 @@ ++ } ++ ++ locale_failure: ++- printf("could not find a UTF8 locale ... please enable en_US.UTF-8\n"); +++ fprintf(stderr, "could not find a UTF8 locale ... please enable en_US.UTF-8\n"); ++ return EXIT_FAILURE; ++ locale_success: ++ pclose(fp); +diff --git a/packages/uClibc/0.9.31/uClibc-0.9.31-fix-fcntl64-for-64-bit-targets.patch b/packages/uClibc/0.9.31/uClibc-0.9.31-fix-fcntl64-for-64-bit-targets.patch +new file mode 100644 +index 00000000..763bfd39 +--- /dev/null ++++ b/packages/uClibc/0.9.31/uClibc-0.9.31-fix-fcntl64-for-64-bit-targets.patch +@@ -0,0 +1,34 @@ ++From 6f1daaaf2d94c1e6184add44eda38b0781b88cf0 Mon Sep 17 00:00:00 2001 ++From: Rob Landley ++Date: Sun, 16 May 2010 21:41:36 +0000 ++Subject: Fix fcntl64 for 64 bit targets. ++ ++64 bit targets often don't have a separate fcntl64() system call, because they don't need one. ++ ++Signed-off-by: Rob Landley ++Signed-off-by: Austin Foxley ++--- ++diff --git a/include/fcntl.h b/include/fcntl.h ++index e37073f..3cfb25f 100644 ++--- a/include/fcntl.h +++++ b/include/fcntl.h ++@@ -73,7 +73,7 @@ __BEGIN_DECLS ++ ++ This function is a cancellation point and therefore not marked with ++ __THROW. */ ++-#ifndef __USE_FILE_OFFSET64 +++#if !defined(__USE_FILE_OFFSET64) || defined(__LP64__) ++ extern int fcntl (int __fd, int __cmd, ...); ++ libc_hidden_proto(fcntl) ++ #else ++@@ -83,7 +83,7 @@ extern int __REDIRECT (fcntl, (int __fd, int __cmd, ...), fcntl64); ++ # define fcntl fcntl64 ++ # endif ++ #endif ++-#ifdef __USE_LARGEFILE64 +++#if defined(__USE_LARGEFILE64) && !defined(__LP64__) ++ extern int fcntl64 (int __fd, int __cmd, ...); ++ libc_hidden_proto(fcntl64) ++ #endif ++-- ++cgit v0.8.2.1 +diff --git a/packages/uClibc/0.9.31/uClibc-0.9.31-more-workarounds-GCC-PR32219.patch b/packages/uClibc/0.9.31/uClibc-0.9.31-more-workarounds-GCC-PR32219.patch +new file mode 100644 +index 00000000..9e695322 +--- /dev/null ++++ b/packages/uClibc/0.9.31/uClibc-0.9.31-more-workarounds-GCC-PR32219.patch +@@ -0,0 +1,40 @@ ++From aa67771881d65373da448ad5f7a8393f3a1d9469 Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Timo=20Ter=C3=A4s?= ++Date: Wed, 30 Jun 2010 14:46:37 +0300 ++Subject: [PATCH] more workarounds for GCC PR32219 ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++Commit 2e53dd645d5348f207cec7f8595969dc566c5a55 workarounds GCC ++bug when accessing _locale_init and _stdio_init. We need the same ++fix for __errno_location and __h_errno_location otherwise we crash ++calling null with static and non-threaded builds. ++ ++Signed-off-by: Timo Teräs ++Signed-off-by: Bernhard Reutner-Fischer ++--- ++ libc/misc/internals/__uClibc_main.c | 4 ++-- ++ 1 files changed, 2 insertions(+), 2 deletions(-) ++ ++diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c ++index 3f09ad2..58f6643 100644 ++--- a/libc/misc/internals/__uClibc_main.c +++++ b/libc/misc/internals/__uClibc_main.c ++@@ -447,11 +447,11 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, ++ * have resulted in errno being set nonzero, so set it to 0 before ++ * we call main. ++ */ ++- if (likely(__errno_location!=NULL)) +++ if (likely(not_null_ptr(__errno_location))) ++ *(__errno_location()) = 0; ++ ++ /* Set h_errno to 0 as well */ ++- if (likely(__h_errno_location!=NULL)) +++ if (likely(not_null_ptr(__h_errno_location))) ++ *(__h_errno_location()) = 0; ++ ++ #if defined HAVE_CLEANUP_JMP_BUF && defined __UCLIBC_HAS_THREADS_NATIVE__ ++-- ++1.7.1 ++ +diff --git a/packages/uClibc/0.9.31/uClibc-0.9.31-powerpc-ptrace-fix.patch b/packages/uClibc/0.9.31/uClibc-0.9.31-powerpc-ptrace-fix.patch +new file mode 100644 +index 00000000..a5ccecaa +--- /dev/null ++++ b/packages/uClibc/0.9.31/uClibc-0.9.31-powerpc-ptrace-fix.patch +@@ -0,0 +1,62 @@ ++[PATCH] powerpc: add PTRACE_EVENT_ defines needed by ltrace ++ ++Equivalent to the common version and kernel headers. ++ ++Signed-off-by: Peter Korsgaard ++--- ++ libc/sysdeps/linux/powerpc/sys/ptrace.h | 41 +++++++++++++++++++++++++++++++- ++ 1 file changed, 40 insertions(+), 1 deletion(-) ++ ++Index: uClibc-0.9.31/libc/sysdeps/linux/powerpc/sys/ptrace.h ++=================================================================== ++--- uClibc-0.9.31.orig/libc/sysdeps/linux/powerpc/sys/ptrace.h +++++ uClibc-0.9.31/libc/sysdeps/linux/powerpc/sys/ptrace.h ++@@ -79,8 +79,47 @@ enum __ptrace_request ++ #define PT_DETACH PTRACE_DETACH ++ ++ /* Continue and stop at the next (return from) syscall. */ ++- PTRACE_SYSCALL = 24 +++ PTRACE_SYSCALL = 24, ++ #define PT_SYSCALL PTRACE_SYSCALL +++ +++ /* Set ptrace filter options. */ +++ PTRACE_SETOPTIONS = 0x4200, +++#define PT_SETOPTIONS PTRACE_SETOPTIONS +++ +++ /* Get last ptrace message. */ +++ PTRACE_GETEVENTMSG = 0x4201, +++#define PT_GETEVENTMSG PTRACE_GETEVENTMSG +++ +++ /* Get siginfo for process. */ +++ PTRACE_GETSIGINFO = 0x4202, +++#define PT_GETSIGINFO PTRACE_GETSIGINFO +++ +++ /* Set new siginfo for process. */ +++ PTRACE_SETSIGINFO = 0x4203 +++#define PT_SETSIGINFO PTRACE_SETSIGINFO +++}; +++ +++ +++/* Options set using PTRACE_SETOPTIONS. */ +++enum __ptrace_setoptions { +++ PTRACE_O_TRACESYSGOOD = 0x00000001, +++ PTRACE_O_TRACEFORK = 0x00000002, +++ PTRACE_O_TRACEVFORK = 0x00000004, +++ PTRACE_O_TRACECLONE = 0x00000008, +++ PTRACE_O_TRACEEXEC = 0x00000010, +++ PTRACE_O_TRACEVFORKDONE = 0x00000020, +++ PTRACE_O_TRACEEXIT = 0x00000040, +++ PTRACE_O_MASK = 0x0000007f +++}; +++ +++/* Wait extended result codes for the above trace options. */ +++enum __ptrace_eventcodes { +++ PTRACE_EVENT_FORK = 1, +++ PTRACE_EVENT_VFORK = 2, +++ PTRACE_EVENT_CLONE = 3, +++ PTRACE_EVENT_EXEC = 4, +++ PTRACE_EVENT_VFORK_DONE = 5, +++ PTRACE_EVENT_EXIT = 6 ++ }; ++ ++ /* Perform process tracing functions. REQUEST is one of the values +diff --git a/packages/uClibc/0.9.31/uClibc-0.9.31-quad-routines.patch b/packages/uClibc/0.9.31/uClibc-0.9.31-quad-routines.patch +new file mode 100644 +index 00000000..de37c303 +--- /dev/null ++++ b/packages/uClibc/0.9.31/uClibc-0.9.31-quad-routines.patch +@@ -0,0 +1,7393 @@ ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/Makefile.arch uClibc-0.9.31/libc/sysdeps/linux/sparc/Makefile.arch ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/Makefile.arch 2010-10-14 14:03:46.000000000 +0200 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/Makefile.arch 2010-10-14 14:36:34.000000000 +0200 ++@@ -5,8 +5,15 @@ ++ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. ++ # ++ ++-CSRC := brk.c __syscall_error.c qp_ops.c sigaction.c +++CSRC := brk.c __syscall_error.c sigaction.c ++ ++ SSRC := \ ++ __longjmp.S fork.S vfork.S clone.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \ ++ syscall.S urem.S udiv.S umul.S sdiv.S rem.S pipe.S +++ +++CSRC += $(foreach f, \ +++ q_div.c q_fle.c q_mul.c q_qtoll.c q_stoq.c \ +++ mp_clz_tab.c q_dtoq.c q_flt.c q_neg.c q_qtos.c q_sub.c \ +++ q_add.c q_feq.c q_fne.c q_qtod.c q_qtou.c q_ulltoq.c \ +++ q_cmp.c q_fge.c q_itoq.c q_qtoull.c q_util.c \ +++ q_cmpe.c q_fgt.c q_lltoq.c q_qtoi.c q_sqrt.c q_utoq.c, soft-fp/$(f)) ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/double.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/double.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/double.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/double.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,264 @@ +++/* Software floating-point emulation. +++ Definitions for IEEE Double Precision +++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz), +++ David S. Miller (davem@redhat.com) and +++ Peter Maydell (pmaydell@chiark.greenend.org.uk). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++#if _FP_W_TYPE_SIZE < 32 +++#error "Here's a nickel kid. Go buy yourself a real computer." +++#endif +++ +++#if _FP_W_TYPE_SIZE < 64 +++#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) +++#else +++#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE +++#endif +++ +++#define _FP_FRACBITS_D 53 +++#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D) +++#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D) +++#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D) +++#define _FP_EXPBITS_D 11 +++#define _FP_EXPBIAS_D 1023 +++#define _FP_EXPMAX_D 2047 +++ +++#define _FP_QNANBIT_D \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE) +++#define _FP_QNANBIT_SH_D \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) +++#define _FP_IMPLBIT_D \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE) +++#define _FP_IMPLBIT_SH_D \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) +++#define _FP_OVERFLOW_D \ +++ ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE) +++ +++typedef float DFtype __attribute__((mode(DF))); +++ +++#if _FP_W_TYPE_SIZE < 64 +++ +++union _FP_UNION_D +++{ +++ DFtype flt; +++ struct { +++#if __BYTE_ORDER == __BIG_ENDIAN +++ unsigned sign : 1; +++ unsigned exp : _FP_EXPBITS_D; +++ unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; +++ unsigned frac0 : _FP_W_TYPE_SIZE; +++#else +++ unsigned frac0 : _FP_W_TYPE_SIZE; +++ unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; +++ unsigned exp : _FP_EXPBITS_D; +++ unsigned sign : 1; +++#endif +++ } bits __attribute__((packed)); +++}; +++ +++#define FP_DECL_D(X) _FP_DECL(2,X) +++#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val) +++#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val) +++#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X) +++#define FP_PACK_RAW_DP(val,X) \ +++ do { \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_2_P(D,val,X); \ +++ } while (0) +++ +++#define FP_UNPACK_D(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2(D,X,val); \ +++ _FP_UNPACK_CANONICAL(D,2,X); \ +++ } while (0) +++ +++#define FP_UNPACK_DP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2_P(D,X,val); \ +++ _FP_UNPACK_CANONICAL(D,2,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_D(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2(D,X,val); \ +++ _FP_UNPACK_SEMIRAW(D,2,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_DP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2_P(D,X,val); \ +++ _FP_UNPACK_SEMIRAW(D,2,X); \ +++ } while (0) +++ +++#define FP_PACK_D(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(D,2,X); \ +++ _FP_PACK_RAW_2(D,val,X); \ +++ } while (0) +++ +++#define FP_PACK_DP(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(D,2,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_2_P(D,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_D(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(D,2,X); \ +++ _FP_PACK_RAW_2(D,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_DP(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(D,2,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_2_P(D,val,X); \ +++ } while (0) +++ +++#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X) +++#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X) +++#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y) +++#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y) +++#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y) +++#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y) +++#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X) +++#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) +++ +++#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un) +++#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y) +++#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y) +++ +++#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg) +++#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt) +++ +++#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X) +++#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X) +++ +++#else +++ +++union _FP_UNION_D +++{ +++ DFtype flt; +++ struct { +++#if __BYTE_ORDER == __BIG_ENDIAN +++ unsigned sign : 1; +++ unsigned exp : _FP_EXPBITS_D; +++ _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); +++#else +++ _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); +++ unsigned exp : _FP_EXPBITS_D; +++ unsigned sign : 1; +++#endif +++ } bits __attribute__((packed)); +++}; +++ +++#define FP_DECL_D(X) _FP_DECL(1,X) +++#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val) +++#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val) +++#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X) +++#define FP_PACK_RAW_DP(val,X) \ +++ do { \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_1_P(D,val,X); \ +++ } while (0) +++ +++#define FP_UNPACK_D(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_1(D,X,val); \ +++ _FP_UNPACK_CANONICAL(D,1,X); \ +++ } while (0) +++ +++#define FP_UNPACK_DP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_1_P(D,X,val); \ +++ _FP_UNPACK_CANONICAL(D,1,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_D(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2(1,X,val); \ +++ _FP_UNPACK_SEMIRAW(D,1,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_DP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2_P(1,X,val); \ +++ _FP_UNPACK_SEMIRAW(D,1,X); \ +++ } while (0) +++ +++#define FP_PACK_D(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(D,1,X); \ +++ _FP_PACK_RAW_1(D,val,X); \ +++ } while (0) +++ +++#define FP_PACK_DP(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(D,1,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_1_P(D,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_D(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(D,1,X); \ +++ _FP_PACK_RAW_1(D,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_DP(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(D,1,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_1_P(D,val,X); \ +++ } while (0) +++ +++#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X) +++#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X) +++#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y) +++#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y) +++#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y) +++#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y) +++#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X) +++#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) +++ +++/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by +++ the target machine. */ +++ +++#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un) +++#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y) +++#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y) +++ +++#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg) +++#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt) +++ +++#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X) +++#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X) +++ +++#endif /* W_TYPE_SIZE < 64 */ ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/extended.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/extended.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/extended.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/extended.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,431 @@ +++/* Software floating-point emulation. +++ Definitions for IEEE Extended Precision. +++ Copyright (C) 1999,2006,2007 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++#if _FP_W_TYPE_SIZE < 32 +++#error "Here's a nickel, kid. Go buy yourself a real computer." +++#endif +++ +++#if _FP_W_TYPE_SIZE < 64 +++#define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE) +++#else +++#define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE) +++#endif +++ +++#define _FP_FRACBITS_E 64 +++#define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E) +++#define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E) +++#define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E) +++#define _FP_EXPBITS_E 15 +++#define _FP_EXPBIAS_E 16383 +++#define _FP_EXPMAX_E 32767 +++ +++#define _FP_QNANBIT_E \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE) +++#define _FP_QNANBIT_SH_E \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) +++#define _FP_IMPLBIT_E \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE) +++#define _FP_IMPLBIT_SH_E \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) +++#define _FP_OVERFLOW_E \ +++ ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE)) +++ +++typedef float XFtype __attribute__((mode(XF))); +++ +++#if _FP_W_TYPE_SIZE < 64 +++ +++union _FP_UNION_E +++{ +++ XFtype flt; +++ struct +++ { +++#if __BYTE_ORDER == __BIG_ENDIAN +++ unsigned long pad1 : _FP_W_TYPE_SIZE; +++ unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); +++ unsigned long sign : 1; +++ unsigned long exp : _FP_EXPBITS_E; +++ unsigned long frac1 : _FP_W_TYPE_SIZE; +++ unsigned long frac0 : _FP_W_TYPE_SIZE; +++#else +++ unsigned long frac0 : _FP_W_TYPE_SIZE; +++ unsigned long frac1 : _FP_W_TYPE_SIZE; +++ unsigned exp : _FP_EXPBITS_E; +++ unsigned sign : 1; +++#endif /* not bigendian */ +++ } bits __attribute__((packed)); +++}; +++ +++ +++#define FP_DECL_E(X) _FP_DECL(4,X) +++ +++#define FP_UNPACK_RAW_E(X, val) \ +++ do { \ +++ union _FP_UNION_E _flo; _flo.flt = (val); \ +++ \ +++ X##_f[2] = 0; X##_f[3] = 0; \ +++ X##_f[0] = _flo.bits.frac0; \ +++ X##_f[1] = _flo.bits.frac1; \ +++ X##_e = _flo.bits.exp; \ +++ X##_s = _flo.bits.sign; \ +++ } while (0) +++ +++#define FP_UNPACK_RAW_EP(X, val) \ +++ do { \ +++ union _FP_UNION_E *_flo = \ +++ (union _FP_UNION_E *)(val); \ +++ \ +++ X##_f[2] = 0; X##_f[3] = 0; \ +++ X##_f[0] = _flo->bits.frac0; \ +++ X##_f[1] = _flo->bits.frac1; \ +++ X##_e = _flo->bits.exp; \ +++ X##_s = _flo->bits.sign; \ +++ } while (0) +++ +++#define FP_PACK_RAW_E(val, X) \ +++ do { \ +++ union _FP_UNION_E _flo; \ +++ \ +++ if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ +++ else X##_f[1] &= ~(_FP_IMPLBIT_E); \ +++ _flo.bits.frac0 = X##_f[0]; \ +++ _flo.bits.frac1 = X##_f[1]; \ +++ _flo.bits.exp = X##_e; \ +++ _flo.bits.sign = X##_s; \ +++ \ +++ (val) = _flo.flt; \ +++ } while (0) +++ +++#define FP_PACK_RAW_EP(val, X) \ +++ do { \ +++ if (!FP_INHIBIT_RESULTS) \ +++ { \ +++ union _FP_UNION_E *_flo = \ +++ (union _FP_UNION_E *)(val); \ +++ \ +++ if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ +++ else X##_f[1] &= ~(_FP_IMPLBIT_E); \ +++ _flo->bits.frac0 = X##_f[0]; \ +++ _flo->bits.frac1 = X##_f[1]; \ +++ _flo->bits.exp = X##_e; \ +++ _flo->bits.sign = X##_s; \ +++ } \ +++ } while (0) +++ +++#define FP_UNPACK_E(X,val) \ +++ do { \ +++ FP_UNPACK_RAW_E(X,val); \ +++ _FP_UNPACK_CANONICAL(E,4,X); \ +++ } while (0) +++ +++#define FP_UNPACK_EP(X,val) \ +++ do { \ +++ FP_UNPACK_RAW_EP(X,val); \ +++ _FP_UNPACK_CANONICAL(E,4,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_E(X,val) \ +++ do { \ +++ FP_UNPACK_RAW_E(X,val); \ +++ _FP_UNPACK_SEMIRAW(E,4,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_EP(X,val) \ +++ do { \ +++ FP_UNPACK_RAW_EP(X,val); \ +++ _FP_UNPACK_SEMIRAW(E,4,X); \ +++ } while (0) +++ +++#define FP_PACK_E(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(E,4,X); \ +++ FP_PACK_RAW_E(val,X); \ +++ } while (0) +++ +++#define FP_PACK_EP(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(E,4,X); \ +++ FP_PACK_RAW_EP(val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_E(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(E,4,X); \ +++ FP_PACK_RAW_E(val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_EP(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(E,4,X); \ +++ FP_PACK_RAW_EP(val,X); \ +++ } while (0) +++ +++#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X) +++#define FP_NEG_E(R,X) _FP_NEG(E,4,R,X) +++#define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y) +++#define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y) +++#define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y) +++#define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y) +++#define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X) +++ +++/* +++ * Square root algorithms: +++ * We have just one right now, maybe Newton approximation +++ * should be added for those machines where division is fast. +++ * This has special _E version because standard _4 square +++ * root would not work (it has to start normally with the +++ * second word and not the first), but as we have to do it +++ * anyway, we optimize it by doing most of the calculations +++ * in two UWtype registers instead of four. +++ */ +++ +++#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ +++ do { \ +++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ +++ _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \ +++ while (q) \ +++ { \ +++ T##_f[1] = S##_f[1] + q; \ +++ if (T##_f[1] <= X##_f[1]) \ +++ { \ +++ S##_f[1] = T##_f[1] + q; \ +++ X##_f[1] -= T##_f[1]; \ +++ R##_f[1] += q; \ +++ } \ +++ _FP_FRAC_SLL_2(X, 1); \ +++ q >>= 1; \ +++ } \ +++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ +++ while (q) \ +++ { \ +++ T##_f[0] = S##_f[0] + q; \ +++ T##_f[1] = S##_f[1]; \ +++ if (T##_f[1] < X##_f[1] || \ +++ (T##_f[1] == X##_f[1] && \ +++ T##_f[0] <= X##_f[0])) \ +++ { \ +++ S##_f[0] = T##_f[0] + q; \ +++ S##_f[1] += (T##_f[0] > S##_f[0]); \ +++ _FP_FRAC_DEC_2(X, T); \ +++ R##_f[0] += q; \ +++ } \ +++ _FP_FRAC_SLL_2(X, 1); \ +++ q >>= 1; \ +++ } \ +++ _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \ +++ if (X##_f[0] | X##_f[1]) \ +++ { \ +++ if (S##_f[1] < X##_f[1] || \ +++ (S##_f[1] == X##_f[1] && \ +++ S##_f[0] < X##_f[0])) \ +++ R##_f[0] |= _FP_WORK_ROUND; \ +++ R##_f[0] |= _FP_WORK_STICKY; \ +++ } \ +++ } while (0) +++ +++#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un) +++#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y) +++#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,4,r,X,Y) +++ +++#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg) +++#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt) +++ +++#define _FP_FRAC_HIGH_E(X) (X##_f[2]) +++#define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1]) +++ +++#else /* not _FP_W_TYPE_SIZE < 64 */ +++union _FP_UNION_E +++{ +++ XFtype flt; +++ struct { +++#if __BYTE_ORDER == __BIG_ENDIAN +++ _FP_W_TYPE pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); +++ unsigned sign : 1; +++ unsigned exp : _FP_EXPBITS_E; +++ _FP_W_TYPE frac : _FP_W_TYPE_SIZE; +++#else +++ _FP_W_TYPE frac : _FP_W_TYPE_SIZE; +++ unsigned exp : _FP_EXPBITS_E; +++ unsigned sign : 1; +++#endif +++ } bits; +++}; +++ +++#define FP_DECL_E(X) _FP_DECL(2,X) +++ +++#define FP_UNPACK_RAW_E(X, val) \ +++ do { \ +++ union _FP_UNION_E _flo; _flo.flt = (val); \ +++ \ +++ X##_f0 = _flo.bits.frac; \ +++ X##_f1 = 0; \ +++ X##_e = _flo.bits.exp; \ +++ X##_s = _flo.bits.sign; \ +++ } while (0) +++ +++#define FP_UNPACK_RAW_EP(X, val) \ +++ do { \ +++ union _FP_UNION_E *_flo = \ +++ (union _FP_UNION_E *)(val); \ +++ \ +++ X##_f0 = _flo->bits.frac; \ +++ X##_f1 = 0; \ +++ X##_e = _flo->bits.exp; \ +++ X##_s = _flo->bits.sign; \ +++ } while (0) +++ +++#define FP_PACK_RAW_E(val, X) \ +++ do { \ +++ union _FP_UNION_E _flo; \ +++ \ +++ if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ +++ else X##_f0 &= ~(_FP_IMPLBIT_E); \ +++ _flo.bits.frac = X##_f0; \ +++ _flo.bits.exp = X##_e; \ +++ _flo.bits.sign = X##_s; \ +++ \ +++ (val) = _flo.flt; \ +++ } while (0) +++ +++#define FP_PACK_RAW_EP(fs, val, X) \ +++ do { \ +++ if (!FP_INHIBIT_RESULTS) \ +++ { \ +++ union _FP_UNION_E *_flo = \ +++ (union _FP_UNION_E *)(val); \ +++ \ +++ if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ +++ else X##_f0 &= ~(_FP_IMPLBIT_E); \ +++ _flo->bits.frac = X##_f0; \ +++ _flo->bits.exp = X##_e; \ +++ _flo->bits.sign = X##_s; \ +++ } \ +++ } while (0) +++ +++ +++#define FP_UNPACK_E(X,val) \ +++ do { \ +++ FP_UNPACK_RAW_E(X,val); \ +++ _FP_UNPACK_CANONICAL(E,2,X); \ +++ } while (0) +++ +++#define FP_UNPACK_EP(X,val) \ +++ do { \ +++ FP_UNPACK_RAW_EP(X,val); \ +++ _FP_UNPACK_CANONICAL(E,2,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_E(X,val) \ +++ do { \ +++ FP_UNPACK_RAW_E(X,val); \ +++ _FP_UNPACK_SEMIRAW(E,2,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_EP(X,val) \ +++ do { \ +++ FP_UNPACK_RAW_EP(X,val); \ +++ _FP_UNPACK_SEMIRAW(E,2,X); \ +++ } while (0) +++ +++#define FP_PACK_E(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(E,2,X); \ +++ FP_PACK_RAW_E(val,X); \ +++ } while (0) +++ +++#define FP_PACK_EP(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(E,2,X); \ +++ FP_PACK_RAW_EP(val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_E(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(E,2,X); \ +++ FP_PACK_RAW_E(val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_EP(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(E,2,X); \ +++ FP_PACK_RAW_EP(val,X); \ +++ } while (0) +++ +++#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X) +++#define FP_NEG_E(R,X) _FP_NEG(E,2,R,X) +++#define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y) +++#define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y) +++#define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y) +++#define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y) +++#define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X) +++ +++/* +++ * Square root algorithms: +++ * We have just one right now, maybe Newton approximation +++ * should be added for those machines where division is fast. +++ * We optimize it by doing most of the calculations +++ * in one UWtype registers instead of two, although we don't +++ * have to. +++ */ +++#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ +++ do { \ +++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ +++ _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \ +++ while (q) \ +++ { \ +++ T##_f0 = S##_f0 + q; \ +++ if (T##_f0 <= X##_f0) \ +++ { \ +++ S##_f0 = T##_f0 + q; \ +++ X##_f0 -= T##_f0; \ +++ R##_f0 += q; \ +++ } \ +++ _FP_FRAC_SLL_1(X, 1); \ +++ q >>= 1; \ +++ } \ +++ _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \ +++ if (X##_f0) \ +++ { \ +++ if (S##_f0 < X##_f0) \ +++ R##_f0 |= _FP_WORK_ROUND; \ +++ R##_f0 |= _FP_WORK_STICKY; \ +++ } \ +++ } while (0) +++ +++#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un) +++#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y) +++#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,2,r,X,Y) +++ +++#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg) +++#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt) +++ +++#define _FP_FRAC_HIGH_E(X) (X##_f1) +++#define _FP_FRAC_HIGH_RAW_E(X) (X##_f0) +++ +++#endif /* not _FP_W_TYPE_SIZE < 64 */ ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/longlong.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/longlong.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/longlong.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/longlong.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,1461 @@ +++/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. +++ Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +++ 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +++ +++ This file is part of the GNU C Library. +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++/* You have to define the following before including this file: +++ +++ UWtype -- An unsigned type, default type for operations (typically a "word") +++ UHWtype -- An unsigned type, at least half the size of UWtype. +++ UDWtype -- An unsigned type, at least twice as large a UWtype +++ W_TYPE_SIZE -- size in bits of UWtype +++ +++ UQItype -- Unsigned 8 bit type. +++ SItype, USItype -- Signed and unsigned 32 bit types. +++ DItype, UDItype -- Signed and unsigned 64 bit types. +++ +++ On a 32 bit machine UWtype should typically be USItype; +++ on a 64 bit machine, UWtype should typically be UDItype. */ +++ +++#define __BITS4 (W_TYPE_SIZE / 4) +++#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) +++#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) +++#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) +++ +++#ifndef W_TYPE_SIZE +++#define W_TYPE_SIZE 32 +++#define UWtype USItype +++#define UHWtype USItype +++#define UDWtype UDItype +++#endif +++ +++extern const UQItype __clz_tab[256] attribute_hidden; +++ +++/* Define auxiliary asm macros. +++ +++ 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two +++ UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype +++ word product in HIGH_PROD and LOW_PROD. +++ +++ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a +++ UDWtype product. This is just a variant of umul_ppmm. +++ +++ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, +++ denominator) divides a UDWtype, composed by the UWtype integers +++ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient +++ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less +++ than DENOMINATOR for correct operation. If, in addition, the most +++ significant bit of DENOMINATOR must be 1, then the pre-processor symbol +++ UDIV_NEEDS_NORMALIZATION is defined to 1. +++ +++ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, +++ denominator). Like udiv_qrnnd but the numbers are signed. The quotient +++ is rounded towards 0. +++ +++ 5) count_leading_zeros(count, x) counts the number of zero-bits from the +++ msb to the first nonzero bit in the UWtype X. This is the number of +++ steps X needs to be shifted left to set the msb. Undefined for X == 0, +++ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. +++ +++ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts +++ from the least significant end. +++ +++ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, +++ high_addend_2, low_addend_2) adds two UWtype integers, composed by +++ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 +++ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow +++ (i.e. carry out) is not stored anywhere, and is lost. +++ +++ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, +++ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, +++ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and +++ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE +++ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, +++ and is lost. +++ +++ If any of these macros are left undefined for a particular CPU, +++ C macros are used. */ +++ +++/* The CPUs come in alphabetical order below. +++ +++ Please add support for more CPUs here, or improve the current support +++ for the CPUs below! +++ (E.g. WE32100, IBM360.) */ +++ +++#if defined (__GNUC__) && !defined (NO_ASM) +++ +++/* We sometimes need to clobber "cc" with gcc2, but that would not be +++ understood by gcc1. Use cpp to avoid major code duplication. */ +++#if __GNUC__ < 2 +++#define __CLOBBER_CC +++#define __AND_CLOBBER_CC +++#else /* __GNUC__ >= 2 */ +++#define __CLOBBER_CC : "cc" +++#define __AND_CLOBBER_CC , "cc" +++#endif /* __GNUC__ < 2 */ +++ +++#if defined (__alpha) && W_TYPE_SIZE == 64 +++#define umul_ppmm(ph, pl, m0, m1) \ +++ do { \ +++ UDItype __m0 = (m0), __m1 = (m1); \ +++ (ph) = __builtin_alpha_umulh (__m0, __m1); \ +++ (pl) = __m0 * __m1; \ +++ } while (0) +++#define UMUL_TIME 46 +++#ifndef LONGLONG_STANDALONE +++#define udiv_qrnnd(q, r, n1, n0, d) \ +++ do { UDItype __r; \ +++ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ +++ (r) = __r; \ +++ } while (0) +++extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); +++#define UDIV_TIME 220 +++#endif /* LONGLONG_STANDALONE */ +++#ifdef __alpha_cix__ +++#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) +++#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) +++#define COUNT_LEADING_ZEROS_0 64 +++#else +++#define count_leading_zeros(COUNT,X) \ +++ do { \ +++ UDItype __xr = (X), __t, __a; \ +++ __t = __builtin_alpha_cmpbge (0, __xr); \ +++ __a = __clz_tab[__t ^ 0xff] - 1; \ +++ __t = __builtin_alpha_extbl (__xr, __a); \ +++ (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ +++ } while (0) +++#define count_trailing_zeros(COUNT,X) \ +++ do { \ +++ UDItype __xr = (X), __t, __a; \ +++ __t = __builtin_alpha_cmpbge (0, __xr); \ +++ __t = ~__t & -~__t; \ +++ __a = ((__t & 0xCC) != 0) * 2; \ +++ __a += ((__t & 0xF0) != 0) * 4; \ +++ __a += ((__t & 0xAA) != 0); \ +++ __t = __builtin_alpha_extbl (__xr, __a); \ +++ __a <<= 3; \ +++ __t &= -__t; \ +++ __a += ((__t & 0xCC) != 0) * 2; \ +++ __a += ((__t & 0xF0) != 0) * 4; \ +++ __a += ((__t & 0xAA) != 0); \ +++ (COUNT) = __a; \ +++ } while (0) +++#endif /* __alpha_cix__ */ +++#endif /* __alpha */ +++ +++#if defined (__arc__) && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "%r" ((USItype) (ah)), \ +++ "rIJ" ((USItype) (bh)), \ +++ "%r" ((USItype) (al)), \ +++ "rIJ" ((USItype) (bl))) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "r" ((USItype) (ah)), \ +++ "rIJ" ((USItype) (bh)), \ +++ "r" ((USItype) (al)), \ +++ "rIJ" ((USItype) (bl))) +++/* Call libgcc routine. */ +++#define umul_ppmm(w1, w0, u, v) \ +++do { \ +++ DWunion __w; \ +++ __w.ll = __umulsidi3 (u, v); \ +++ w1 = __w.s.high; \ +++ w0 = __w.s.low; \ +++} while (0) +++#define __umulsidi3 __umulsidi3 +++UDItype __umulsidi3 (USItype, USItype); +++#endif +++ +++#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "%r" ((USItype) (ah)), \ +++ "rI" ((USItype) (bh)), \ +++ "%r" ((USItype) (al)), \ +++ "rI" ((USItype) (bl)) __CLOBBER_CC) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "r" ((USItype) (ah)), \ +++ "rI" ((USItype) (bh)), \ +++ "r" ((USItype) (al)), \ +++ "rI" ((USItype) (bl)) __CLOBBER_CC) +++#define umul_ppmm(xh, xl, a, b) \ +++{register USItype __t0, __t1, __t2; \ +++ __asm__ ("%@ Inlined umul_ppmm\n" \ +++ " mov %2, %5, lsr #16\n" \ +++ " mov %0, %6, lsr #16\n" \ +++ " bic %3, %5, %2, lsl #16\n" \ +++ " bic %4, %6, %0, lsl #16\n" \ +++ " mul %1, %3, %4\n" \ +++ " mul %4, %2, %4\n" \ +++ " mul %3, %0, %3\n" \ +++ " mul %0, %2, %0\n" \ +++ " adds %3, %4, %3\n" \ +++ " addcs %0, %0, #65536\n" \ +++ " adds %1, %1, %3, lsl #16\n" \ +++ " adc %0, %0, %3, lsr #16" \ +++ : "=&r" ((USItype) (xh)), \ +++ "=r" ((USItype) (xl)), \ +++ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ +++ : "r" ((USItype) (a)), \ +++ "r" ((USItype) (b)) __CLOBBER_CC );} +++#define UMUL_TIME 20 +++#define UDIV_TIME 100 +++#endif /* __arm__ */ +++ +++#if defined(__arm__) +++/* Let gcc decide how best to implement count_leading_zeros. */ +++#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) +++#define COUNT_LEADING_ZEROS_0 32 +++#endif +++ +++#if defined (__CRIS__) && __CRIS_arch_version >= 3 +++#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) +++#if __CRIS_arch_version >= 8 +++#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) +++#endif +++#endif /* __CRIS__ */ +++ +++#if defined (__hppa) && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "%rM" ((USItype) (ah)), \ +++ "rM" ((USItype) (bh)), \ +++ "%rM" ((USItype) (al)), \ +++ "rM" ((USItype) (bl))) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "rM" ((USItype) (ah)), \ +++ "rM" ((USItype) (bh)), \ +++ "rM" ((USItype) (al)), \ +++ "rM" ((USItype) (bl))) +++#if defined (_PA_RISC1_1) +++#define umul_ppmm(w1, w0, u, v) \ +++ do { \ +++ union \ +++ { \ +++ UDItype __f; \ +++ struct {USItype __w1, __w0;} __w1w0; \ +++ } __t; \ +++ __asm__ ("xmpyu %1,%2,%0" \ +++ : "=x" (__t.__f) \ +++ : "x" ((USItype) (u)), \ +++ "x" ((USItype) (v))); \ +++ (w1) = __t.__w1w0.__w1; \ +++ (w0) = __t.__w1w0.__w0; \ +++ } while (0) +++#define UMUL_TIME 8 +++#else +++#define UMUL_TIME 30 +++#endif +++#define UDIV_TIME 40 +++#define count_leading_zeros(count, x) \ +++ do { \ +++ USItype __tmp; \ +++ __asm__ ( \ +++ "ldi 1,%0\n" \ +++" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ +++" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ +++" ldo 16(%0),%0 ; Yes. Perform add.\n" \ +++" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ +++" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ +++" ldo 8(%0),%0 ; Yes. Perform add.\n" \ +++" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ +++" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ +++" ldo 4(%0),%0 ; Yes. Perform add.\n" \ +++" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ +++" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ +++" ldo 2(%0),%0 ; Yes. Perform add.\n" \ +++" extru %1,30,1,%1 ; Extract bit 1.\n" \ +++" sub %0,%1,%0 ; Subtract it.\n" \ +++ : "=r" (count), "=r" (__tmp) : "1" (x)); \ +++ } while (0) +++#endif +++ +++#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32 +++#define smul_ppmm(xh, xl, m0, m1) \ +++ do { \ +++ union {DItype __ll; \ +++ struct {USItype __h, __l;} __i; \ +++ } __x; \ +++ __asm__ ("lr %N0,%1\n\tmr %0,%2" \ +++ : "=&r" (__x.__ll) \ +++ : "r" (m0), "r" (m1)); \ +++ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ +++ } while (0) +++#define sdiv_qrnnd(q, r, n1, n0, d) \ +++ do { \ +++ union {DItype __ll; \ +++ struct {USItype __h, __l;} __i; \ +++ } __x; \ +++ __x.__i.__h = n1; __x.__i.__l = n0; \ +++ __asm__ ("dr %0,%2" \ +++ : "=r" (__x.__ll) \ +++ : "0" (__x.__ll), "r" (d)); \ +++ (q) = __x.__i.__l; (r) = __x.__i.__h; \ +++ } while (0) +++#endif +++ +++#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("add{l} {%5,%1|%1,%5}\n\tadc{l} {%3,%0|%0,%3}" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "%0" ((USItype) (ah)), \ +++ "g" ((USItype) (bh)), \ +++ "%1" ((USItype) (al)), \ +++ "g" ((USItype) (bl))) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("sub{l} {%5,%1|%1,%5}\n\tsbb{l} {%3,%0|%0,%3}" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "0" ((USItype) (ah)), \ +++ "g" ((USItype) (bh)), \ +++ "1" ((USItype) (al)), \ +++ "g" ((USItype) (bl))) +++#define umul_ppmm(w1, w0, u, v) \ +++ __asm__ ("mul{l} %3" \ +++ : "=a" ((USItype) (w0)), \ +++ "=d" ((USItype) (w1)) \ +++ : "%0" ((USItype) (u)), \ +++ "rm" ((USItype) (v))) +++#define udiv_qrnnd(q, r, n1, n0, dv) \ +++ __asm__ ("div{l} %4" \ +++ : "=a" ((USItype) (q)), \ +++ "=d" ((USItype) (r)) \ +++ : "0" ((USItype) (n0)), \ +++ "1" ((USItype) (n1)), \ +++ "rm" ((USItype) (dv))) +++#define count_leading_zeros(count, x) ((count) = __builtin_clz (x)) +++#define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x)) +++#define UMUL_TIME 40 +++#define UDIV_TIME 40 +++#endif /* 80x86 */ +++ +++#if (defined (__x86_64__) || defined (__i386__)) && W_TYPE_SIZE == 64 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("add{q} {%5,%1|%1,%5}\n\tadc{q} {%3,%0|%0,%3}" \ +++ : "=r" ((UDItype) (sh)), \ +++ "=&r" ((UDItype) (sl)) \ +++ : "%0" ((UDItype) (ah)), \ +++ "rme" ((UDItype) (bh)), \ +++ "%1" ((UDItype) (al)), \ +++ "rme" ((UDItype) (bl))) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("sub{q} {%5,%1|%1,%5}\n\tsbb{q} {%3,%0|%0,%3}" \ +++ : "=r" ((UDItype) (sh)), \ +++ "=&r" ((UDItype) (sl)) \ +++ : "0" ((UDItype) (ah)), \ +++ "rme" ((UDItype) (bh)), \ +++ "1" ((UDItype) (al)), \ +++ "rme" ((UDItype) (bl))) +++#define umul_ppmm(w1, w0, u, v) \ +++ __asm__ ("mul{q} %3" \ +++ : "=a" ((UDItype) (w0)), \ +++ "=d" ((UDItype) (w1)) \ +++ : "%0" ((UDItype) (u)), \ +++ "rm" ((UDItype) (v))) +++#define udiv_qrnnd(q, r, n1, n0, dv) \ +++ __asm__ ("div{q} %4" \ +++ : "=a" ((UDItype) (q)), \ +++ "=d" ((UDItype) (r)) \ +++ : "0" ((UDItype) (n0)), \ +++ "1" ((UDItype) (n1)), \ +++ "rm" ((UDItype) (dv))) +++#define count_leading_zeros(count, x) ((count) = __builtin_clzl (x)) +++#define count_trailing_zeros(count, x) ((count) = __builtin_ctzl (x)) +++#define UMUL_TIME 40 +++#define UDIV_TIME 40 +++#endif /* x86_64 */ +++ +++#if defined (__i960__) && W_TYPE_SIZE == 32 +++#define umul_ppmm(w1, w0, u, v) \ +++ ({union {UDItype __ll; \ +++ struct {USItype __l, __h;} __i; \ +++ } __xx; \ +++ __asm__ ("emul %2,%1,%0" \ +++ : "=d" (__xx.__ll) \ +++ : "%dI" ((USItype) (u)), \ +++ "dI" ((USItype) (v))); \ +++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +++#define __umulsidi3(u, v) \ +++ ({UDItype __w; \ +++ __asm__ ("emul %2,%1,%0" \ +++ : "=d" (__w) \ +++ : "%dI" ((USItype) (u)), \ +++ "dI" ((USItype) (v))); \ +++ __w; }) +++#endif /* __i960__ */ +++ +++#if defined (__M32R__) && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ /* The cmp clears the condition bit. */ \ +++ __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "0" ((USItype) (ah)), \ +++ "r" ((USItype) (bh)), \ +++ "1" ((USItype) (al)), \ +++ "r" ((USItype) (bl)) \ +++ : "cbit") +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ /* The cmp clears the condition bit. */ \ +++ __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "0" ((USItype) (ah)), \ +++ "r" ((USItype) (bh)), \ +++ "1" ((USItype) (al)), \ +++ "r" ((USItype) (bl)) \ +++ : "cbit") +++#endif /* __M32R__ */ +++ +++#if defined (__mc68000__) && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ +++ : "=d" ((USItype) (sh)), \ +++ "=&d" ((USItype) (sl)) \ +++ : "%0" ((USItype) (ah)), \ +++ "d" ((USItype) (bh)), \ +++ "%1" ((USItype) (al)), \ +++ "g" ((USItype) (bl))) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ +++ : "=d" ((USItype) (sh)), \ +++ "=&d" ((USItype) (sl)) \ +++ : "0" ((USItype) (ah)), \ +++ "d" ((USItype) (bh)), \ +++ "1" ((USItype) (al)), \ +++ "g" ((USItype) (bl))) +++ +++/* The '020, '030, '040, '060 and CPU32 have 32x32->64 and 64/32->32q-32r. */ +++#if (defined (__mc68020__) && !defined (__mc68060__)) +++#define umul_ppmm(w1, w0, u, v) \ +++ __asm__ ("mulu%.l %3,%1:%0" \ +++ : "=d" ((USItype) (w0)), \ +++ "=d" ((USItype) (w1)) \ +++ : "%0" ((USItype) (u)), \ +++ "dmi" ((USItype) (v))) +++#define UMUL_TIME 45 +++#define udiv_qrnnd(q, r, n1, n0, d) \ +++ __asm__ ("divu%.l %4,%1:%0" \ +++ : "=d" ((USItype) (q)), \ +++ "=d" ((USItype) (r)) \ +++ : "0" ((USItype) (n0)), \ +++ "1" ((USItype) (n1)), \ +++ "dmi" ((USItype) (d))) +++#define UDIV_TIME 90 +++#define sdiv_qrnnd(q, r, n1, n0, d) \ +++ __asm__ ("divs%.l %4,%1:%0" \ +++ : "=d" ((USItype) (q)), \ +++ "=d" ((USItype) (r)) \ +++ : "0" ((USItype) (n0)), \ +++ "1" ((USItype) (n1)), \ +++ "dmi" ((USItype) (d))) +++ +++#elif defined (__mcoldfire__) /* not mc68020 */ +++ +++#define umul_ppmm(xh, xl, a, b) \ +++ __asm__ ("| Inlined umul_ppmm\n" \ +++ " move%.l %2,%/d0\n" \ +++ " move%.l %3,%/d1\n" \ +++ " move%.l %/d0,%/d2\n" \ +++ " swap %/d0\n" \ +++ " move%.l %/d1,%/d3\n" \ +++ " swap %/d1\n" \ +++ " move%.w %/d2,%/d4\n" \ +++ " mulu %/d3,%/d4\n" \ +++ " mulu %/d1,%/d2\n" \ +++ " mulu %/d0,%/d3\n" \ +++ " mulu %/d0,%/d1\n" \ +++ " move%.l %/d4,%/d0\n" \ +++ " clr%.w %/d0\n" \ +++ " swap %/d0\n" \ +++ " add%.l %/d0,%/d2\n" \ +++ " add%.l %/d3,%/d2\n" \ +++ " jcc 1f\n" \ +++ " add%.l %#65536,%/d1\n" \ +++ "1: swap %/d2\n" \ +++ " moveq %#0,%/d0\n" \ +++ " move%.w %/d2,%/d0\n" \ +++ " move%.w %/d4,%/d2\n" \ +++ " move%.l %/d2,%1\n" \ +++ " add%.l %/d1,%/d0\n" \ +++ " move%.l %/d0,%0" \ +++ : "=g" ((USItype) (xh)), \ +++ "=g" ((USItype) (xl)) \ +++ : "g" ((USItype) (a)), \ +++ "g" ((USItype) (b)) \ +++ : "d0", "d1", "d2", "d3", "d4") +++#define UMUL_TIME 100 +++#define UDIV_TIME 400 +++#else /* not ColdFire */ +++/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ +++#define umul_ppmm(xh, xl, a, b) \ +++ __asm__ ("| Inlined umul_ppmm\n" \ +++ " move%.l %2,%/d0\n" \ +++ " move%.l %3,%/d1\n" \ +++ " move%.l %/d0,%/d2\n" \ +++ " swap %/d0\n" \ +++ " move%.l %/d1,%/d3\n" \ +++ " swap %/d1\n" \ +++ " move%.w %/d2,%/d4\n" \ +++ " mulu %/d3,%/d4\n" \ +++ " mulu %/d1,%/d2\n" \ +++ " mulu %/d0,%/d3\n" \ +++ " mulu %/d0,%/d1\n" \ +++ " move%.l %/d4,%/d0\n" \ +++ " eor%.w %/d0,%/d0\n" \ +++ " swap %/d0\n" \ +++ " add%.l %/d0,%/d2\n" \ +++ " add%.l %/d3,%/d2\n" \ +++ " jcc 1f\n" \ +++ " add%.l %#65536,%/d1\n" \ +++ "1: swap %/d2\n" \ +++ " moveq %#0,%/d0\n" \ +++ " move%.w %/d2,%/d0\n" \ +++ " move%.w %/d4,%/d2\n" \ +++ " move%.l %/d2,%1\n" \ +++ " add%.l %/d1,%/d0\n" \ +++ " move%.l %/d0,%0" \ +++ : "=g" ((USItype) (xh)), \ +++ "=g" ((USItype) (xl)) \ +++ : "g" ((USItype) (a)), \ +++ "g" ((USItype) (b)) \ +++ : "d0", "d1", "d2", "d3", "d4") +++#define UMUL_TIME 100 +++#define UDIV_TIME 400 +++ +++#endif /* not mc68020 */ +++ +++/* The '020, '030, '040 and '060 have bitfield insns. +++ cpu32 disguises as a 68020, but lacks them. */ +++#if defined (__mc68020__) && !defined (__mcpu32__) +++#define count_leading_zeros(count, x) \ +++ __asm__ ("bfffo %1{%b2:%b2},%0" \ +++ : "=d" ((USItype) (count)) \ +++ : "od" ((USItype) (x)), "n" (0)) +++/* Some ColdFire architectures have a ff1 instruction supported via +++ __builtin_clz. */ +++#elif defined (__mcfisaaplus__) || defined (__mcfisac__) +++#define count_leading_zeros(count,x) ((count) = __builtin_clz (x)) +++#define COUNT_LEADING_ZEROS_0 32 +++#endif +++#endif /* mc68000 */ +++ +++#if defined (__m88000__) && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "%rJ" ((USItype) (ah)), \ +++ "rJ" ((USItype) (bh)), \ +++ "%rJ" ((USItype) (al)), \ +++ "rJ" ((USItype) (bl))) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "rJ" ((USItype) (ah)), \ +++ "rJ" ((USItype) (bh)), \ +++ "rJ" ((USItype) (al)), \ +++ "rJ" ((USItype) (bl))) +++#define count_leading_zeros(count, x) \ +++ do { \ +++ USItype __cbtmp; \ +++ __asm__ ("ff1 %0,%1" \ +++ : "=r" (__cbtmp) \ +++ : "r" ((USItype) (x))); \ +++ (count) = __cbtmp ^ 31; \ +++ } while (0) +++#define COUNT_LEADING_ZEROS_0 63 /* sic */ +++#if defined (__mc88110__) +++#define umul_ppmm(wh, wl, u, v) \ +++ do { \ +++ union {UDItype __ll; \ +++ struct {USItype __h, __l;} __i; \ +++ } __xx; \ +++ __asm__ ("mulu.d %0,%1,%2" \ +++ : "=r" (__xx.__ll) \ +++ : "r" ((USItype) (u)), \ +++ "r" ((USItype) (v))); \ +++ (wh) = __xx.__i.__h; \ +++ (wl) = __xx.__i.__l; \ +++ } while (0) +++#define udiv_qrnnd(q, r, n1, n0, d) \ +++ ({union {UDItype __ll; \ +++ struct {USItype __h, __l;} __i; \ +++ } __xx; \ +++ USItype __q; \ +++ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ +++ __asm__ ("divu.d %0,%1,%2" \ +++ : "=r" (__q) \ +++ : "r" (__xx.__ll), \ +++ "r" ((USItype) (d))); \ +++ (r) = (n0) - __q * (d); (q) = __q; }) +++#define UMUL_TIME 5 +++#define UDIV_TIME 25 +++#else +++#define UMUL_TIME 17 +++#define UDIV_TIME 150 +++#endif /* __mc88110__ */ +++#endif /* __m88000__ */ +++ +++#if defined (__mips__) && W_TYPE_SIZE == 32 +++#define umul_ppmm(w1, w0, u, v) \ +++ do { \ +++ UDItype __x = (UDItype) (USItype) (u) * (USItype) (v); \ +++ (w1) = (USItype) (__x >> 32); \ +++ (w0) = (USItype) (__x); \ +++ } while (0) +++#define UMUL_TIME 10 +++#define UDIV_TIME 100 +++ +++#if (__mips == 32 || __mips == 64) && ! __mips16 +++#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) +++#define COUNT_LEADING_ZEROS_0 32 +++#endif +++#endif /* __mips__ */ +++ +++#if defined (__ns32000__) && W_TYPE_SIZE == 32 +++#define umul_ppmm(w1, w0, u, v) \ +++ ({union {UDItype __ll; \ +++ struct {USItype __l, __h;} __i; \ +++ } __xx; \ +++ __asm__ ("meid %2,%0" \ +++ : "=g" (__xx.__ll) \ +++ : "%0" ((USItype) (u)), \ +++ "g" ((USItype) (v))); \ +++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +++#define __umulsidi3(u, v) \ +++ ({UDItype __w; \ +++ __asm__ ("meid %2,%0" \ +++ : "=g" (__w) \ +++ : "%0" ((USItype) (u)), \ +++ "g" ((USItype) (v))); \ +++ __w; }) +++#define udiv_qrnnd(q, r, n1, n0, d) \ +++ ({union {UDItype __ll; \ +++ struct {USItype __l, __h;} __i; \ +++ } __xx; \ +++ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ +++ __asm__ ("deid %2,%0" \ +++ : "=g" (__xx.__ll) \ +++ : "0" (__xx.__ll), \ +++ "g" ((USItype) (d))); \ +++ (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) +++#define count_trailing_zeros(count,x) \ +++ do { \ +++ __asm__ ("ffsd %2,%0" \ +++ : "=r" ((USItype) (count)) \ +++ : "0" ((USItype) 0), \ +++ "r" ((USItype) (x))); \ +++ } while (0) +++#endif /* __ns32000__ */ +++ +++/* FIXME: We should test _IBMR2 here when we add assembly support for the +++ system vendor compilers. +++ FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good +++ enough, since that hits ARM and m68k too. */ +++#if (defined (_ARCH_PPC) /* AIX */ \ +++ || defined (_ARCH_PWR) /* AIX */ \ +++ || defined (_ARCH_COM) /* AIX */ \ +++ || defined (__powerpc__) /* gcc */ \ +++ || defined (__POWERPC__) /* BEOS */ \ +++ || defined (__ppc__) /* Darwin */ \ +++ || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ +++ || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ +++ && CPU_FAMILY == PPC) \ +++ ) && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ do { \ +++ if (__builtin_constant_p (bh) && (bh) == 0) \ +++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ +++ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ +++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ +++ else \ +++ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ +++ : "=r" (sh), "=&r" (sl) \ +++ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ +++ } while (0) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ do { \ +++ if (__builtin_constant_p (ah) && (ah) == 0) \ +++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ +++ else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ +++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ +++ else if (__builtin_constant_p (bh) && (bh) == 0) \ +++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ +++ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ +++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ +++ else \ +++ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ +++ : "=r" (sh), "=&r" (sl) \ +++ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ +++ } while (0) +++#define count_leading_zeros(count, x) \ +++ __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) +++#define COUNT_LEADING_ZEROS_0 32 +++#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ +++ || defined (__ppc__) \ +++ || (defined (PPC) && ! defined (CPU_FAMILY)) /* gcc 2.7.x GNU&SysV */ \ +++ || (defined (PPC) && defined (CPU_FAMILY) /* VxWorks */ \ +++ && CPU_FAMILY == PPC) +++#define umul_ppmm(ph, pl, m0, m1) \ +++ do { \ +++ USItype __m0 = (m0), __m1 = (m1); \ +++ __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ +++ (pl) = __m0 * __m1; \ +++ } while (0) +++#define UMUL_TIME 15 +++#define smul_ppmm(ph, pl, m0, m1) \ +++ do { \ +++ SItype __m0 = (m0), __m1 = (m1); \ +++ __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ +++ (pl) = __m0 * __m1; \ +++ } while (0) +++#define SMUL_TIME 14 +++#define UDIV_TIME 120 +++#elif defined (_ARCH_PWR) +++#define UMUL_TIME 8 +++#define smul_ppmm(xh, xl, m0, m1) \ +++ __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) +++#define SMUL_TIME 4 +++#define sdiv_qrnnd(q, r, nh, nl, d) \ +++ __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) +++#define UDIV_TIME 100 +++#endif +++#endif /* 32-bit POWER architecture variants. */ +++ +++/* We should test _IBMR2 here when we add assembly support for the system +++ vendor compilers. */ +++#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ do { \ +++ if (__builtin_constant_p (bh) && (bh) == 0) \ +++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ +++ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ +++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ +++ else \ +++ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ +++ : "=r" (sh), "=&r" (sl) \ +++ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ +++ } while (0) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ do { \ +++ if (__builtin_constant_p (ah) && (ah) == 0) \ +++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ +++ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ +++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ +++ else if (__builtin_constant_p (bh) && (bh) == 0) \ +++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ +++ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ +++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ +++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ +++ else \ +++ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ +++ : "=r" (sh), "=&r" (sl) \ +++ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ +++ } while (0) +++#define count_leading_zeros(count, x) \ +++ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) +++#define COUNT_LEADING_ZEROS_0 64 +++#define umul_ppmm(ph, pl, m0, m1) \ +++ do { \ +++ UDItype __m0 = (m0), __m1 = (m1); \ +++ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ +++ (pl) = __m0 * __m1; \ +++ } while (0) +++#define UMUL_TIME 15 +++#define smul_ppmm(ph, pl, m0, m1) \ +++ do { \ +++ DItype __m0 = (m0), __m1 = (m1); \ +++ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ +++ (pl) = __m0 * __m1; \ +++ } while (0) +++#define SMUL_TIME 14 /* ??? */ +++#define UDIV_TIME 120 /* ??? */ +++#endif /* 64-bit PowerPC. */ +++ +++#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("a %1,%5\n\tae %0,%3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "%0" ((USItype) (ah)), \ +++ "r" ((USItype) (bh)), \ +++ "%1" ((USItype) (al)), \ +++ "r" ((USItype) (bl))) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("s %1,%5\n\tse %0,%3" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "0" ((USItype) (ah)), \ +++ "r" ((USItype) (bh)), \ +++ "1" ((USItype) (al)), \ +++ "r" ((USItype) (bl))) +++#define umul_ppmm(ph, pl, m0, m1) \ +++ do { \ +++ USItype __m0 = (m0), __m1 = (m1); \ +++ __asm__ ( \ +++ "s r2,r2\n" \ +++" mts r10,%2\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" m r2,%3\n" \ +++" cas %0,r2,r0\n" \ +++" mfs r10,%1" \ +++ : "=r" ((USItype) (ph)), \ +++ "=r" ((USItype) (pl)) \ +++ : "%r" (__m0), \ +++ "r" (__m1) \ +++ : "r2"); \ +++ (ph) += ((((SItype) __m0 >> 31) & __m1) \ +++ + (((SItype) __m1 >> 31) & __m0)); \ +++ } while (0) +++#define UMUL_TIME 20 +++#define UDIV_TIME 200 +++#define count_leading_zeros(count, x) \ +++ do { \ +++ if ((x) >= 0x10000) \ +++ __asm__ ("clz %0,%1" \ +++ : "=r" ((USItype) (count)) \ +++ : "r" ((USItype) (x) >> 16)); \ +++ else \ +++ { \ +++ __asm__ ("clz %0,%1" \ +++ : "=r" ((USItype) (count)) \ +++ : "r" ((USItype) (x))); \ +++ (count) += 16; \ +++ } \ +++ } while (0) +++#endif +++ +++#if defined(__sh__) && !__SHMEDIA__ && W_TYPE_SIZE == 32 +++#ifndef __sh1__ +++#define umul_ppmm(w1, w0, u, v) \ +++ __asm__ ( \ +++ "dmulu.l %2,%3\n\tsts%M1 macl,%1\n\tsts%M0 mach,%0" \ +++ : "=r<" ((USItype)(w1)), \ +++ "=r<" ((USItype)(w0)) \ +++ : "r" ((USItype)(u)), \ +++ "r" ((USItype)(v)) \ +++ : "macl", "mach") +++#define UMUL_TIME 5 +++#endif +++ +++/* This is the same algorithm as __udiv_qrnnd_c. */ +++#define UDIV_NEEDS_NORMALIZATION 1 +++ +++#define udiv_qrnnd(q, r, n1, n0, d) \ +++ do { \ +++ extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \ +++ __attribute__ ((visibility ("hidden"))); \ +++ /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \ +++ __asm__ ( \ +++ "mov%M4 %4,r5\n" \ +++" swap.w %3,r4\n" \ +++" swap.w r5,r6\n" \ +++" jsr @%5\n" \ +++" shll16 r6\n" \ +++" swap.w r4,r4\n" \ +++" jsr @%5\n" \ +++" swap.w r1,%0\n" \ +++" or r1,%0" \ +++ : "=r" (q), "=&z" (r) \ +++ : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \ +++ : "r1", "r2", "r4", "r5", "r6", "pr"); \ +++ } while (0) +++ +++#define UDIV_TIME 80 +++ +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("clrt;subc %5,%1; subc %4,%0" \ +++ : "=r" (sh), "=r" (sl) \ +++ : "0" (ah), "1" (al), "r" (bh), "r" (bl)) +++ +++#endif /* __sh__ */ +++ +++#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 +++#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) +++#define count_leading_zeros(count, x) \ +++ do \ +++ { \ +++ UDItype x_ = (USItype)(x); \ +++ SItype c_; \ +++ \ +++ __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ +++ (count) = c_ - 31; \ +++ } \ +++ while (0) +++#define COUNT_LEADING_ZEROS_0 32 +++#endif +++ +++#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ +++ && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "%rJ" ((USItype) (ah)), \ +++ "rI" ((USItype) (bh)), \ +++ "%rJ" ((USItype) (al)), \ +++ "rI" ((USItype) (bl)) \ +++ __CLOBBER_CC) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ +++ : "=r" ((USItype) (sh)), \ +++ "=&r" ((USItype) (sl)) \ +++ : "rJ" ((USItype) (ah)), \ +++ "rI" ((USItype) (bh)), \ +++ "rJ" ((USItype) (al)), \ +++ "rI" ((USItype) (bl)) \ +++ __CLOBBER_CC) +++#if defined (__sparc_v8__) +++#define umul_ppmm(w1, w0, u, v) \ +++ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ +++ : "=r" ((USItype) (w1)), \ +++ "=r" ((USItype) (w0)) \ +++ : "r" ((USItype) (u)), \ +++ "r" ((USItype) (v))) +++#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ +++ __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ +++ : "=&r" ((USItype) (__q)), \ +++ "=&r" ((USItype) (__r)) \ +++ : "r" ((USItype) (__n1)), \ +++ "r" ((USItype) (__n0)), \ +++ "r" ((USItype) (__d))) +++#else +++#if defined (__sparclite__) +++/* This has hardware multiply but not divide. It also has two additional +++ instructions scan (ffs from high bit) and divscc. */ +++#define umul_ppmm(w1, w0, u, v) \ +++ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ +++ : "=r" ((USItype) (w1)), \ +++ "=r" ((USItype) (w0)) \ +++ : "r" ((USItype) (u)), \ +++ "r" ((USItype) (v))) +++#define udiv_qrnnd(q, r, n1, n0, d) \ +++ __asm__ ("! Inlined udiv_qrnnd\n" \ +++" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ +++" tst %%g0\n" \ +++" divscc %3,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%%g1\n" \ +++" divscc %%g1,%4,%0\n" \ +++" rd %%y,%1\n" \ +++" bl,a 1f\n" \ +++" add %1,%4,%1\n" \ +++"1: ! End of inline udiv_qrnnd" \ +++ : "=r" ((USItype) (q)), \ +++ "=r" ((USItype) (r)) \ +++ : "r" ((USItype) (n1)), \ +++ "r" ((USItype) (n0)), \ +++ "rI" ((USItype) (d)) \ +++ : "g1" __AND_CLOBBER_CC) +++#define UDIV_TIME 37 +++#define count_leading_zeros(count, x) \ +++ do { \ +++ __asm__ ("scan %1,1,%0" \ +++ : "=r" ((USItype) (count)) \ +++ : "r" ((USItype) (x))); \ +++ } while (0) +++/* Early sparclites return 63 for an argument of 0, but they warn that future +++ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 +++ undefined. */ +++#else +++/* SPARC without integer multiplication and divide instructions. +++ (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ +++#define umul_ppmm(w1, w0, u, v) \ +++ __asm__ ("! Inlined umul_ppmm\n" \ +++" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ +++" sra %3,31,%%o5 ! Don't move this insn\n" \ +++" and %2,%%o5,%%o5 ! Don't move this insn\n" \ +++" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,%3,%%g1\n" \ +++" mulscc %%g1,0,%%g1\n" \ +++" add %%g1,%%o5,%0\n" \ +++" rd %%y,%1" \ +++ : "=r" ((USItype) (w1)), \ +++ "=r" ((USItype) (w0)) \ +++ : "%rI" ((USItype) (u)), \ +++ "r" ((USItype) (v)) \ +++ : "g1", "o5" __AND_CLOBBER_CC) +++#define UMUL_TIME 39 /* 39 instructions */ +++/* It's quite necessary to add this much assembler for the sparc. +++ The default udiv_qrnnd (in C) is more than 10 times slower! */ +++#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ +++ __asm__ ("! Inlined udiv_qrnnd\n" \ +++" mov 32,%%g1\n" \ +++" subcc %1,%2,%%g0\n" \ +++"1: bcs 5f\n" \ +++" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +++" sub %1,%2,%1 ! this kills msb of n\n" \ +++" addx %1,%1,%1 ! so this can't give carry\n" \ +++" subcc %%g1,1,%%g1\n" \ +++"2: bne 1b\n" \ +++" subcc %1,%2,%%g0\n" \ +++" bcs 3f\n" \ +++" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +++" b 3f\n" \ +++" sub %1,%2,%1 ! this kills msb of n\n" \ +++"4: sub %1,%2,%1\n" \ +++"5: addxcc %1,%1,%1\n" \ +++" bcc 2b\n" \ +++" subcc %%g1,1,%%g1\n" \ +++"! Got carry from n. Subtract next step to cancel this carry.\n" \ +++" bne 4b\n" \ +++" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ +++" sub %1,%2,%1\n" \ +++"3: xnor %0,0,%0\n" \ +++" ! End of inline udiv_qrnnd" \ +++ : "=&r" ((USItype) (__q)), \ +++ "=&r" ((USItype) (__r)) \ +++ : "r" ((USItype) (__d)), \ +++ "1" ((USItype) (__n1)), \ +++ "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) +++#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ +++#endif /* __sparclite__ */ +++#endif /* __sparc_v8__ */ +++#endif /* sparc32 */ +++ +++#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ +++ && W_TYPE_SIZE == 64 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("addcc %r4,%5,%1\n\t" \ +++ "add %r2,%3,%0\n\t" \ +++ "bcs,a,pn %%xcc, 1f\n\t" \ +++ "add %0, 1, %0\n" \ +++ "1:" \ +++ : "=r" ((UDItype)(sh)), \ +++ "=&r" ((UDItype)(sl)) \ +++ : "%rJ" ((UDItype)(ah)), \ +++ "rI" ((UDItype)(bh)), \ +++ "%rJ" ((UDItype)(al)), \ +++ "rI" ((UDItype)(bl)) \ +++ __CLOBBER_CC) +++ +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("subcc %r4,%5,%1\n\t" \ +++ "sub %r2,%3,%0\n\t" \ +++ "bcs,a,pn %%xcc, 1f\n\t" \ +++ "sub %0, 1, %0\n\t" \ +++ "1:" \ +++ : "=r" ((UDItype)(sh)), \ +++ "=&r" ((UDItype)(sl)) \ +++ : "rJ" ((UDItype)(ah)), \ +++ "rI" ((UDItype)(bh)), \ +++ "rJ" ((UDItype)(al)), \ +++ "rI" ((UDItype)(bl)) \ +++ __CLOBBER_CC) +++ +++#define umul_ppmm(wh, wl, u, v) \ +++ do { \ +++ UDItype tmp1, tmp2, tmp3, tmp4; \ +++ __asm__ __volatile__ ( \ +++ "srl %7,0,%3\n\t" \ +++ "mulx %3,%6,%1\n\t" \ +++ "srlx %6,32,%2\n\t" \ +++ "mulx %2,%3,%4\n\t" \ +++ "sllx %4,32,%5\n\t" \ +++ "srl %6,0,%3\n\t" \ +++ "sub %1,%5,%5\n\t" \ +++ "srlx %5,32,%5\n\t" \ +++ "addcc %4,%5,%4\n\t" \ +++ "srlx %7,32,%5\n\t" \ +++ "mulx %3,%5,%3\n\t" \ +++ "mulx %2,%5,%5\n\t" \ +++ "sethi %%hi(0x80000000),%2\n\t" \ +++ "addcc %4,%3,%4\n\t" \ +++ "srlx %4,32,%4\n\t" \ +++ "add %2,%2,%2\n\t" \ +++ "movcc %%xcc,%%g0,%2\n\t" \ +++ "addcc %5,%4,%5\n\t" \ +++ "sllx %3,32,%3\n\t" \ +++ "add %1,%3,%1\n\t" \ +++ "add %5,%2,%0" \ +++ : "=r" ((UDItype)(wh)), \ +++ "=&r" ((UDItype)(wl)), \ +++ "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ +++ : "r" ((UDItype)(u)), \ +++ "r" ((UDItype)(v)) \ +++ __CLOBBER_CC); \ +++ } while (0) +++#define UMUL_TIME 96 +++#define UDIV_TIME 230 +++#endif /* sparc64 */ +++ +++#if defined (__vax__) && W_TYPE_SIZE == 32 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ +++ : "=g" ((USItype) (sh)), \ +++ "=&g" ((USItype) (sl)) \ +++ : "%0" ((USItype) (ah)), \ +++ "g" ((USItype) (bh)), \ +++ "%1" ((USItype) (al)), \ +++ "g" ((USItype) (bl))) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ +++ : "=g" ((USItype) (sh)), \ +++ "=&g" ((USItype) (sl)) \ +++ : "0" ((USItype) (ah)), \ +++ "g" ((USItype) (bh)), \ +++ "1" ((USItype) (al)), \ +++ "g" ((USItype) (bl))) +++#define umul_ppmm(xh, xl, m0, m1) \ +++ do { \ +++ union { \ +++ UDItype __ll; \ +++ struct {USItype __l, __h;} __i; \ +++ } __xx; \ +++ USItype __m0 = (m0), __m1 = (m1); \ +++ __asm__ ("emul %1,%2,$0,%0" \ +++ : "=r" (__xx.__ll) \ +++ : "g" (__m0), \ +++ "g" (__m1)); \ +++ (xh) = __xx.__i.__h; \ +++ (xl) = __xx.__i.__l; \ +++ (xh) += ((((SItype) __m0 >> 31) & __m1) \ +++ + (((SItype) __m1 >> 31) & __m0)); \ +++ } while (0) +++#define sdiv_qrnnd(q, r, n1, n0, d) \ +++ do { \ +++ union {DItype __ll; \ +++ struct {SItype __l, __h;} __i; \ +++ } __xx; \ +++ __xx.__i.__h = n1; __xx.__i.__l = n0; \ +++ __asm__ ("ediv %3,%2,%0,%1" \ +++ : "=g" (q), "=g" (r) \ +++ : "g" (__xx.__ll), "g" (d)); \ +++ } while (0) +++#endif /* __vax__ */ +++ +++#if defined (__xtensa__) && W_TYPE_SIZE == 32 +++/* This code is not Xtensa-configuration-specific, so rely on the compiler +++ to expand builtin functions depending on what configuration features +++ are available. This avoids library calls when the operation can be +++ performed in-line. */ +++#define umul_ppmm(w1, w0, u, v) \ +++ do { \ +++ DWunion __w; \ +++ __w.ll = __builtin_umulsidi3 (u, v); \ +++ w1 = __w.s.high; \ +++ w0 = __w.s.low; \ +++ } while (0) +++#define __umulsidi3(u, v) __builtin_umulsidi3 (u, v) +++#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) +++#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) +++#endif /* __xtensa__ */ +++ +++#if defined (__z8000__) && W_TYPE_SIZE == 16 +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ +++ : "=r" ((unsigned int)(sh)), \ +++ "=&r" ((unsigned int)(sl)) \ +++ : "%0" ((unsigned int)(ah)), \ +++ "r" ((unsigned int)(bh)), \ +++ "%1" ((unsigned int)(al)), \ +++ "rQR" ((unsigned int)(bl))) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ +++ : "=r" ((unsigned int)(sh)), \ +++ "=&r" ((unsigned int)(sl)) \ +++ : "0" ((unsigned int)(ah)), \ +++ "r" ((unsigned int)(bh)), \ +++ "1" ((unsigned int)(al)), \ +++ "rQR" ((unsigned int)(bl))) +++#define umul_ppmm(xh, xl, m0, m1) \ +++ do { \ +++ union {long int __ll; \ +++ struct {unsigned int __h, __l;} __i; \ +++ } __xx; \ +++ unsigned int __m0 = (m0), __m1 = (m1); \ +++ __asm__ ("mult %S0,%H3" \ +++ : "=r" (__xx.__i.__h), \ +++ "=r" (__xx.__i.__l) \ +++ : "%1" (__m0), \ +++ "rQR" (__m1)); \ +++ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ +++ (xh) += ((((signed int) __m0 >> 15) & __m1) \ +++ + (((signed int) __m1 >> 15) & __m0)); \ +++ } while (0) +++#endif /* __z8000__ */ +++ +++#endif /* __GNUC__ */ +++ +++/* If this machine has no inline assembler, use C macros. */ +++ +++#if !defined (add_ssaaaa) +++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +++ do { \ +++ UWtype __x; \ +++ __x = (al) + (bl); \ +++ (sh) = (ah) + (bh) + (__x < (al)); \ +++ (sl) = __x; \ +++ } while (0) +++#endif +++ +++#if !defined (sub_ddmmss) +++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +++ do { \ +++ UWtype __x; \ +++ __x = (al) - (bl); \ +++ (sh) = (ah) - (bh) - (__x > (al)); \ +++ (sl) = __x; \ +++ } while (0) +++#endif +++ +++/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of +++ smul_ppmm. */ +++#if !defined (umul_ppmm) && defined (smul_ppmm) +++#define umul_ppmm(w1, w0, u, v) \ +++ do { \ +++ UWtype __w1; \ +++ UWtype __xm0 = (u), __xm1 = (v); \ +++ smul_ppmm (__w1, w0, __xm0, __xm1); \ +++ (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \ +++ + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \ +++ } while (0) +++#endif +++ +++/* If we still don't have umul_ppmm, define it using plain C. */ +++#if !defined (umul_ppmm) +++#define umul_ppmm(w1, w0, u, v) \ +++ do { \ +++ UWtype __x0, __x1, __x2, __x3; \ +++ UHWtype __ul, __vl, __uh, __vh; \ +++ \ +++ __ul = __ll_lowpart (u); \ +++ __uh = __ll_highpart (u); \ +++ __vl = __ll_lowpart (v); \ +++ __vh = __ll_highpart (v); \ +++ \ +++ __x0 = (UWtype) __ul * __vl; \ +++ __x1 = (UWtype) __ul * __vh; \ +++ __x2 = (UWtype) __uh * __vl; \ +++ __x3 = (UWtype) __uh * __vh; \ +++ \ +++ __x1 += __ll_highpart (__x0);/* this can't give carry */ \ +++ __x1 += __x2; /* but this indeed can */ \ +++ if (__x1 < __x2) /* did we get it? */ \ +++ __x3 += __ll_B; /* yes, add it in the proper pos. */ \ +++ \ +++ (w1) = __x3 + __ll_highpart (__x1); \ +++ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ +++ } while (0) +++#endif +++ +++#if !defined (__umulsidi3) +++#define __umulsidi3(u, v) \ +++ ({DWunion __w; \ +++ umul_ppmm (__w.s.high, __w.s.low, u, v); \ +++ __w.ll; }) +++#endif +++ +++/* Define this unconditionally, so it can be used for debugging. */ +++#define __udiv_qrnnd_c(q, r, n1, n0, d) \ +++ do { \ +++ UWtype __d1, __d0, __q1, __q0; \ +++ UWtype __r1, __r0, __m; \ +++ __d1 = __ll_highpart (d); \ +++ __d0 = __ll_lowpart (d); \ +++ \ +++ __r1 = (n1) % __d1; \ +++ __q1 = (n1) / __d1; \ +++ __m = (UWtype) __q1 * __d0; \ +++ __r1 = __r1 * __ll_B | __ll_highpart (n0); \ +++ if (__r1 < __m) \ +++ { \ +++ __q1--, __r1 += (d); \ +++ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ +++ if (__r1 < __m) \ +++ __q1--, __r1 += (d); \ +++ } \ +++ __r1 -= __m; \ +++ \ +++ __r0 = __r1 % __d1; \ +++ __q0 = __r1 / __d1; \ +++ __m = (UWtype) __q0 * __d0; \ +++ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ +++ if (__r0 < __m) \ +++ { \ +++ __q0--, __r0 += (d); \ +++ if (__r0 >= (d)) \ +++ if (__r0 < __m) \ +++ __q0--, __r0 += (d); \ +++ } \ +++ __r0 -= __m; \ +++ \ +++ (q) = (UWtype) __q1 * __ll_B | __q0; \ +++ (r) = __r0; \ +++ } while (0) +++ +++/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through +++ __udiv_w_sdiv (defined in libgcc or elsewhere). */ +++#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) +++#define udiv_qrnnd(q, r, nh, nl, d) \ +++ do { \ +++ USItype __r; \ +++ (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ +++ (r) = __r; \ +++ } while (0) +++#endif +++ +++/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ +++#if !defined (udiv_qrnnd) +++#define UDIV_NEEDS_NORMALIZATION 1 +++#define udiv_qrnnd __udiv_qrnnd_c +++#endif +++ +++#if !defined (count_leading_zeros) +++#define count_leading_zeros(count, x) \ +++ do { \ +++ UWtype __xr = (x); \ +++ UWtype __a; \ +++ \ +++ if (W_TYPE_SIZE <= 32) \ +++ { \ +++ __a = __xr < ((UWtype)1<<2*__BITS4) \ +++ ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ +++ : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ +++ } \ +++ else \ +++ { \ +++ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ +++ if (((__xr >> __a) & 0xff) != 0) \ +++ break; \ +++ } \ +++ \ +++ (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ +++ } while (0) +++#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE +++#endif +++ +++#if !defined (count_trailing_zeros) +++/* Define count_trailing_zeros using count_leading_zeros. The latter might be +++ defined in asm, but if it is not, the C version above is good enough. */ +++#define count_trailing_zeros(count, x) \ +++ do { \ +++ UWtype __ctz_x = (x); \ +++ UWtype __ctz_c; \ +++ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ +++ (count) = W_TYPE_SIZE - 1 - __ctz_c; \ +++ } while (0) +++#endif +++ +++#ifndef UDIV_NEEDS_NORMALIZATION +++#define UDIV_NEEDS_NORMALIZATION 0 +++#endif ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/mp_clz_tab.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,37 @@ +++/* __clz_tab -- support for longlong.h +++ Copyright (C) 1991, 1993, 1994, 1997 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. Its master source is NOT part of +++ the C library, however. The master source lives in the GNU MP Library. +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#if 0 +++#include +++#include "gmp-impl.h" +++#endif +++ +++const +++unsigned char __clz_tab[] = +++{ +++ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, +++ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, +++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +++}; ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-1.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-1.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-1.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-1.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,302 @@ +++/* Software floating-point emulation. +++ Basic one-word fraction declaration and manipulation. +++ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz), +++ David S. Miller (davem@redhat.com) and +++ Peter Maydell (pmaydell@chiark.greenend.org.uk). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f +++#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f) +++#define _FP_FRAC_SET_1(X,I) (X##_f = I) +++#define _FP_FRAC_HIGH_1(X) (X##_f) +++#define _FP_FRAC_LOW_1(X) (X##_f) +++#define _FP_FRAC_WORD_1(X,w) (X##_f) +++ +++#define _FP_FRAC_ADDI_1(X,I) (X##_f += I) +++#define _FP_FRAC_SLL_1(X,N) \ +++ do { \ +++ if (__builtin_constant_p(N) && (N) == 1) \ +++ X##_f += X##_f; \ +++ else \ +++ X##_f <<= (N); \ +++ } while (0) +++#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N) +++ +++/* Right shift with sticky-lsb. */ +++#define _FP_FRAC_SRST_1(X,S,N,sz) __FP_FRAC_SRST_1(X##_f, S, N, sz) +++#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz) +++ +++#define __FP_FRAC_SRST_1(X,S,N,sz) \ +++do { \ +++ S = (__builtin_constant_p(N) && (N) == 1 \ +++ ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \ +++ X = X >> (N); \ +++} while (0) +++ +++#define __FP_FRAC_SRS_1(X,N,sz) \ +++ (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \ +++ ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) +++ +++#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f) +++#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f) +++#define _FP_FRAC_DEC_1(X,Y) (X##_f -= Y##_f) +++#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f) +++ +++/* Predicates */ +++#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0) +++#define _FP_FRAC_ZEROP_1(X) (X##_f == 0) +++#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs) +++#define _FP_FRAC_CLEAR_OVERP_1(fs,X) (X##_f &= ~_FP_OVERFLOW_##fs) +++#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f) +++#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f) +++#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f) +++ +++#define _FP_ZEROFRAC_1 0 +++#define _FP_MINFRAC_1 1 +++#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE)0) +++ +++/* +++ * Unpack the raw bits of a native fp value. Do not classify or +++ * normalize the data. +++ */ +++ +++#define _FP_UNPACK_RAW_1(fs, X, val) \ +++ do { \ +++ union _FP_UNION_##fs _flo; _flo.flt = (val); \ +++ \ +++ X##_f = _flo.bits.frac; \ +++ X##_e = _flo.bits.exp; \ +++ X##_s = _flo.bits.sign; \ +++ } while (0) +++ +++#define _FP_UNPACK_RAW_1_P(fs, X, val) \ +++ do { \ +++ union _FP_UNION_##fs *_flo = \ +++ (union _FP_UNION_##fs *)(val); \ +++ \ +++ X##_f = _flo->bits.frac; \ +++ X##_e = _flo->bits.exp; \ +++ X##_s = _flo->bits.sign; \ +++ } while (0) +++ +++/* +++ * Repack the raw bits of a native fp value. +++ */ +++ +++#define _FP_PACK_RAW_1(fs, val, X) \ +++ do { \ +++ union _FP_UNION_##fs _flo; \ +++ \ +++ _flo.bits.frac = X##_f; \ +++ _flo.bits.exp = X##_e; \ +++ _flo.bits.sign = X##_s; \ +++ \ +++ (val) = _flo.flt; \ +++ } while (0) +++ +++#define _FP_PACK_RAW_1_P(fs, val, X) \ +++ do { \ +++ union _FP_UNION_##fs *_flo = \ +++ (union _FP_UNION_##fs *)(val); \ +++ \ +++ _flo->bits.frac = X##_f; \ +++ _flo->bits.exp = X##_e; \ +++ _flo->bits.sign = X##_s; \ +++ } while (0) +++ +++ +++/* +++ * Multiplication algorithms: +++ */ +++ +++/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the +++ multiplication immediately. */ +++ +++#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \ +++ do { \ +++ R##_f = X##_f * Y##_f; \ +++ /* Normalize since we know where the msb of the multiplicands \ +++ were (bit B), we know that the msb of the of the product is \ +++ at either 2B or 2B-1. */ \ +++ _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \ +++ } while (0) +++ +++/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ +++ +++#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \ +++ do { \ +++ _FP_W_TYPE _Z_f0, _Z_f1; \ +++ doit(_Z_f1, _Z_f0, X##_f, Y##_f); \ +++ /* Normalize since we know where the msb of the multiplicands \ +++ were (bit B), we know that the msb of the of the product is \ +++ at either 2B or 2B-1. */ \ +++ _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \ +++ R##_f = _Z_f0; \ +++ } while (0) +++ +++/* Finally, a simple widening multiply algorithm. What fun! */ +++ +++#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \ +++ do { \ +++ _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \ +++ \ +++ /* split the words in half */ \ +++ _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ +++ _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ +++ _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ +++ _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ +++ \ +++ /* multiply the pieces */ \ +++ _z_f0 = _xl * _yl; \ +++ _a_f0 = _xh * _yl; \ +++ _a_f1 = _xl * _yh; \ +++ _z_f1 = _xh * _yh; \ +++ \ +++ /* reassemble into two full words */ \ +++ if ((_a_f0 += _a_f1) < _a_f1) \ +++ _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \ +++ _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ +++ _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ +++ _FP_FRAC_ADD_2(_z, _z, _a); \ +++ \ +++ /* normalize */ \ +++ _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \ +++ R##_f = _z_f0; \ +++ } while (0) +++ +++ +++/* +++ * Division algorithms: +++ */ +++ +++/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the +++ division immediately. Give this macro either _FP_DIV_HELP_imm for +++ C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you +++ choose will depend on what the compiler does with divrem4. */ +++ +++#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ +++ do { \ +++ _FP_W_TYPE _q, _r; \ +++ X##_f <<= (X##_f < Y##_f \ +++ ? R##_e--, _FP_WFRACBITS_##fs \ +++ : _FP_WFRACBITS_##fs - 1); \ +++ doit(_q, _r, X##_f, Y##_f); \ +++ R##_f = _q | (_r != 0); \ +++ } while (0) +++ +++/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd +++ that may be useful in this situation. This first is for a primitive +++ that requires normalization, the second for one that does not. Look +++ for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */ +++ +++#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \ +++ do { \ +++ _FP_W_TYPE _nh, _nl, _q, _r, _y; \ +++ \ +++ /* Normalize Y -- i.e. make the most significant bit set. */ \ +++ _y = Y##_f << _FP_WFRACXBITS_##fs; \ +++ \ +++ /* Shift X op correspondingly high, that is, up one full word. */ \ +++ if (X##_f < Y##_f) \ +++ { \ +++ R##_e--; \ +++ _nl = 0; \ +++ _nh = X##_f; \ +++ } \ +++ else \ +++ { \ +++ _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \ +++ _nh = X##_f >> 1; \ +++ } \ +++ \ +++ udiv_qrnnd(_q, _r, _nh, _nl, _y); \ +++ R##_f = _q | (_r != 0); \ +++ } while (0) +++ +++#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \ +++ do { \ +++ _FP_W_TYPE _nh, _nl, _q, _r; \ +++ if (X##_f < Y##_f) \ +++ { \ +++ R##_e--; \ +++ _nl = X##_f << _FP_WFRACBITS_##fs; \ +++ _nh = X##_f >> _FP_WFRACXBITS_##fs; \ +++ } \ +++ else \ +++ { \ +++ _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ +++ _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ +++ } \ +++ udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ +++ R##_f = _q | (_r != 0); \ +++ } while (0) +++ +++ +++/* +++ * Square root algorithms: +++ * We have just one right now, maybe Newton approximation +++ * should be added for those machines where division is fast. +++ */ +++ +++#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ +++ do { \ +++ while (q != _FP_WORK_ROUND) \ +++ { \ +++ T##_f = S##_f + q; \ +++ if (T##_f <= X##_f) \ +++ { \ +++ S##_f = T##_f + q; \ +++ X##_f -= T##_f; \ +++ R##_f += q; \ +++ } \ +++ _FP_FRAC_SLL_1(X, 1); \ +++ q >>= 1; \ +++ } \ +++ if (X##_f) \ +++ { \ +++ if (S##_f < X##_f) \ +++ R##_f |= _FP_WORK_ROUND; \ +++ R##_f |= _FP_WORK_STICKY; \ +++ } \ +++ } while (0) +++ +++/* +++ * Assembly/disassembly for converting to/from integral types. +++ * No shifting or overflow handled here. +++ */ +++ +++#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f) +++#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r) +++ +++ +++/* +++ * Convert FP values between word sizes +++ */ +++ +++#define _FP_FRAC_COPY_1_1(D, S) (D##_f = S##_f) ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-2.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-2.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-2.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-2.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,617 @@ +++/* Software floating-point emulation. +++ Basic two-word fraction declaration and manipulation. +++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz), +++ David S. Miller (davem@redhat.com) and +++ Peter Maydell (pmaydell@chiark.greenend.org.uk). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1 +++#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1) +++#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I) +++#define _FP_FRAC_HIGH_2(X) (X##_f1) +++#define _FP_FRAC_LOW_2(X) (X##_f0) +++#define _FP_FRAC_WORD_2(X,w) (X##_f##w) +++ +++#define _FP_FRAC_SLL_2(X,N) \ +++(void)(((N) < _FP_W_TYPE_SIZE) \ +++ ? ({ \ +++ if (__builtin_constant_p(N) && (N) == 1) \ +++ { \ +++ X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \ +++ X##_f0 += X##_f0; \ +++ } \ +++ else \ +++ { \ +++ X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ +++ X##_f0 <<= (N); \ +++ } \ +++ 0; \ +++ }) \ +++ : ({ \ +++ X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ +++ X##_f0 = 0; \ +++ })) +++ +++ +++#define _FP_FRAC_SRL_2(X,N) \ +++(void)(((N) < _FP_W_TYPE_SIZE) \ +++ ? ({ \ +++ X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ +++ X##_f1 >>= (N); \ +++ }) \ +++ : ({ \ +++ X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ +++ X##_f1 = 0; \ +++ })) +++ +++/* Right shift with sticky-lsb. */ +++#define _FP_FRAC_SRST_2(X,S, N,sz) \ +++(void)(((N) < _FP_W_TYPE_SIZE) \ +++ ? ({ \ +++ S = (__builtin_constant_p(N) && (N) == 1 \ +++ ? X##_f0 & 1 \ +++ : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \ +++ X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \ +++ X##_f1 >>= (N); \ +++ }) \ +++ : ({ \ +++ S = ((((N) == _FP_W_TYPE_SIZE \ +++ ? 0 \ +++ : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ +++ | X##_f0) != 0); \ +++ X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \ +++ X##_f1 = 0; \ +++ })) +++ +++#define _FP_FRAC_SRS_2(X,N,sz) \ +++(void)(((N) < _FP_W_TYPE_SIZE) \ +++ ? ({ \ +++ X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \ +++ (__builtin_constant_p(N) && (N) == 1 \ +++ ? X##_f0 & 1 \ +++ : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ +++ X##_f1 >>= (N); \ +++ }) \ +++ : ({ \ +++ X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \ +++ ((((N) == _FP_W_TYPE_SIZE \ +++ ? 0 \ +++ : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ +++ | X##_f0) != 0)); \ +++ X##_f1 = 0; \ +++ })) +++ +++#define _FP_FRAC_ADDI_2(X,I) \ +++ __FP_FRAC_ADDI_2(X##_f1, X##_f0, I) +++ +++#define _FP_FRAC_ADD_2(R,X,Y) \ +++ __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) +++ +++#define _FP_FRAC_SUB_2(R,X,Y) \ +++ __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) +++ +++#define _FP_FRAC_DEC_2(X,Y) \ +++ __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0) +++ +++#define _FP_FRAC_CLZ_2(R,X) \ +++ do { \ +++ if (X##_f1) \ +++ __FP_CLZ(R,X##_f1); \ +++ else \ +++ { \ +++ __FP_CLZ(R,X##_f0); \ +++ R += _FP_W_TYPE_SIZE; \ +++ } \ +++ } while(0) +++ +++/* Predicates */ +++#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0) +++#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0) +++#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) +++#define _FP_FRAC_CLEAR_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) +++#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0) +++#define _FP_FRAC_GT_2(X, Y) \ +++ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0)) +++#define _FP_FRAC_GE_2(X, Y) \ +++ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0)) +++ +++#define _FP_ZEROFRAC_2 0, 0 +++#define _FP_MINFRAC_2 0, 1 +++#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) +++ +++/* +++ * Internals +++ */ +++ +++#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1) +++ +++#define __FP_CLZ_2(R, xh, xl) \ +++ do { \ +++ if (xh) \ +++ __FP_CLZ(R,xh); \ +++ else \ +++ { \ +++ __FP_CLZ(R,xl); \ +++ R += _FP_W_TYPE_SIZE; \ +++ } \ +++ } while(0) +++ +++#if 0 +++ +++#ifndef __FP_FRAC_ADDI_2 +++#define __FP_FRAC_ADDI_2(xh, xl, i) \ +++ (xh += ((xl += i) < i)) +++#endif +++#ifndef __FP_FRAC_ADD_2 +++#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \ +++ (rh = xh + yh + ((rl = xl + yl) < xl)) +++#endif +++#ifndef __FP_FRAC_SUB_2 +++#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \ +++ (rh = xh - yh - ((rl = xl - yl) > xl)) +++#endif +++#ifndef __FP_FRAC_DEC_2 +++#define __FP_FRAC_DEC_2(xh, xl, yh, yl) \ +++ do { \ +++ UWtype _t = xl; \ +++ xh -= yh + ((xl -= yl) > _t); \ +++ } while (0) +++#endif +++ +++#else +++ +++#undef __FP_FRAC_ADDI_2 +++#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i) +++#undef __FP_FRAC_ADD_2 +++#define __FP_FRAC_ADD_2 add_ssaaaa +++#undef __FP_FRAC_SUB_2 +++#define __FP_FRAC_SUB_2 sub_ddmmss +++#undef __FP_FRAC_DEC_2 +++#define __FP_FRAC_DEC_2(xh, xl, yh, yl) sub_ddmmss(xh, xl, xh, xl, yh, yl) +++ +++#endif +++ +++/* +++ * Unpack the raw bits of a native fp value. Do not classify or +++ * normalize the data. +++ */ +++ +++#define _FP_UNPACK_RAW_2(fs, X, val) \ +++ do { \ +++ union _FP_UNION_##fs _flo; _flo.flt = (val); \ +++ \ +++ X##_f0 = _flo.bits.frac0; \ +++ X##_f1 = _flo.bits.frac1; \ +++ X##_e = _flo.bits.exp; \ +++ X##_s = _flo.bits.sign; \ +++ } while (0) +++ +++#define _FP_UNPACK_RAW_2_P(fs, X, val) \ +++ do { \ +++ union _FP_UNION_##fs *_flo = \ +++ (union _FP_UNION_##fs *)(val); \ +++ \ +++ X##_f0 = _flo->bits.frac0; \ +++ X##_f1 = _flo->bits.frac1; \ +++ X##_e = _flo->bits.exp; \ +++ X##_s = _flo->bits.sign; \ +++ } while (0) +++ +++ +++/* +++ * Repack the raw bits of a native fp value. +++ */ +++ +++#define _FP_PACK_RAW_2(fs, val, X) \ +++ do { \ +++ union _FP_UNION_##fs _flo; \ +++ \ +++ _flo.bits.frac0 = X##_f0; \ +++ _flo.bits.frac1 = X##_f1; \ +++ _flo.bits.exp = X##_e; \ +++ _flo.bits.sign = X##_s; \ +++ \ +++ (val) = _flo.flt; \ +++ } while (0) +++ +++#define _FP_PACK_RAW_2_P(fs, val, X) \ +++ do { \ +++ union _FP_UNION_##fs *_flo = \ +++ (union _FP_UNION_##fs *)(val); \ +++ \ +++ _flo->bits.frac0 = X##_f0; \ +++ _flo->bits.frac1 = X##_f1; \ +++ _flo->bits.exp = X##_e; \ +++ _flo->bits.sign = X##_s; \ +++ } while (0) +++ +++ +++/* +++ * Multiplication algorithms: +++ */ +++ +++/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ +++ +++#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \ +++ do { \ +++ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ +++ \ +++ doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ +++ doit(_b_f1, _b_f0, X##_f0, Y##_f1); \ +++ doit(_c_f1, _c_f0, X##_f1, Y##_f0); \ +++ doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \ +++ \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ +++ _FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0, \ +++ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ +++ _FP_FRAC_WORD_4(_z,1)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ +++ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0, \ +++ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ +++ _FP_FRAC_WORD_4(_z,1)); \ +++ \ +++ /* Normalize since we know where the msb of the multiplicands \ +++ were (bit B), we know that the msb of the of the product is \ +++ at either 2B or 2B-1. */ \ +++ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ +++ R##_f0 = _FP_FRAC_WORD_4(_z,0); \ +++ R##_f1 = _FP_FRAC_WORD_4(_z,1); \ +++ } while (0) +++ +++/* Given a 1W * 1W => 2W primitive, do the extended multiplication. +++ Do only 3 multiplications instead of four. This one is for machines +++ where multiplication is much more expensive than subtraction. */ +++ +++#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \ +++ do { \ +++ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ +++ _FP_W_TYPE _d; \ +++ int _c1, _c2; \ +++ \ +++ _b_f0 = X##_f0 + X##_f1; \ +++ _c1 = _b_f0 < X##_f0; \ +++ _b_f1 = Y##_f0 + Y##_f1; \ +++ _c2 = _b_f1 < Y##_f0; \ +++ doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ +++ doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1); \ +++ doit(_c_f1, _c_f0, X##_f1, Y##_f1); \ +++ \ +++ _b_f0 &= -_c2; \ +++ _b_f1 &= -_c1; \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ +++ _FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d, \ +++ 0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1)); \ +++ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ +++ _b_f0); \ +++ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ +++ _b_f1); \ +++ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ +++ _FP_FRAC_WORD_4(_z,1), \ +++ 0, _d, _FP_FRAC_WORD_4(_z,0)); \ +++ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ +++ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0); \ +++ __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), \ +++ _c_f1, _c_f0, \ +++ _FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2)); \ +++ \ +++ /* Normalize since we know where the msb of the multiplicands \ +++ were (bit B), we know that the msb of the of the product is \ +++ at either 2B or 2B-1. */ \ +++ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ +++ R##_f0 = _FP_FRAC_WORD_4(_z,0); \ +++ R##_f1 = _FP_FRAC_WORD_4(_z,1); \ +++ } while (0) +++ +++#define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \ +++ do { \ +++ _FP_FRAC_DECL_4(_z); \ +++ _FP_W_TYPE _x[2], _y[2]; \ +++ _x[0] = X##_f0; _x[1] = X##_f1; \ +++ _y[0] = Y##_f0; _y[1] = Y##_f1; \ +++ \ +++ mpn_mul_n(_z_f, _x, _y, 2); \ +++ \ +++ /* Normalize since we know where the msb of the multiplicands \ +++ were (bit B), we know that the msb of the of the product is \ +++ at either 2B or 2B-1. */ \ +++ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ +++ R##_f0 = _z_f[0]; \ +++ R##_f1 = _z_f[1]; \ +++ } while (0) +++ +++/* Do at most 120x120=240 bits multiplication using double floating +++ point multiplication. This is useful if floating point +++ multiplication has much bigger throughput than integer multiply. +++ It is supposed to work for _FP_W_TYPE_SIZE 64 and wfracbits +++ between 106 and 120 only. +++ Caller guarantees that X and Y has (1LLL << (wfracbits - 1)) set. +++ SETFETZ is a macro which will disable all FPU exceptions and set rounding +++ towards zero, RESETFE should optionally reset it back. */ +++ +++#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \ +++ do { \ +++ static const double _const[] = { \ +++ /* 2^-24 */ 5.9604644775390625e-08, \ +++ /* 2^-48 */ 3.5527136788005009e-15, \ +++ /* 2^-72 */ 2.1175823681357508e-22, \ +++ /* 2^-96 */ 1.2621774483536189e-29, \ +++ /* 2^28 */ 2.68435456e+08, \ +++ /* 2^4 */ 1.600000e+01, \ +++ /* 2^-20 */ 9.5367431640625e-07, \ +++ /* 2^-44 */ 5.6843418860808015e-14, \ +++ /* 2^-68 */ 3.3881317890172014e-21, \ +++ /* 2^-92 */ 2.0194839173657902e-28, \ +++ /* 2^-116 */ 1.2037062152420224e-35}; \ +++ double _a240, _b240, _c240, _d240, _e240, _f240, \ +++ _g240, _h240, _i240, _j240, _k240; \ +++ union { double d; UDItype i; } _l240, _m240, _n240, _o240, \ +++ _p240, _q240, _r240, _s240; \ +++ UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \ +++ \ +++ if (wfracbits < 106 || wfracbits > 120) \ +++ abort(); \ +++ \ +++ setfetz; \ +++ \ +++ _e240 = (double)(long)(X##_f0 & 0xffffff); \ +++ _j240 = (double)(long)(Y##_f0 & 0xffffff); \ +++ _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \ +++ _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \ +++ _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \ +++ _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \ +++ _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \ +++ _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \ +++ _a240 = (double)(long)(X##_f1 >> 32); \ +++ _f240 = (double)(long)(Y##_f1 >> 32); \ +++ _e240 *= _const[3]; \ +++ _j240 *= _const[3]; \ +++ _d240 *= _const[2]; \ +++ _i240 *= _const[2]; \ +++ _c240 *= _const[1]; \ +++ _h240 *= _const[1]; \ +++ _b240 *= _const[0]; \ +++ _g240 *= _const[0]; \ +++ _s240.d = _e240*_j240;\ +++ _r240.d = _d240*_j240 + _e240*_i240;\ +++ _q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240;\ +++ _p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\ +++ _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\ +++ _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \ +++ _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \ +++ _l240.d = _a240*_g240 + _b240*_f240; \ +++ _k240 = _a240*_f240; \ +++ _r240.d += _s240.d; \ +++ _q240.d += _r240.d; \ +++ _p240.d += _q240.d; \ +++ _o240.d += _p240.d; \ +++ _n240.d += _o240.d; \ +++ _m240.d += _n240.d; \ +++ _l240.d += _m240.d; \ +++ _k240 += _l240.d; \ +++ _s240.d -= ((_const[10]+_s240.d)-_const[10]); \ +++ _r240.d -= ((_const[9]+_r240.d)-_const[9]); \ +++ _q240.d -= ((_const[8]+_q240.d)-_const[8]); \ +++ _p240.d -= ((_const[7]+_p240.d)-_const[7]); \ +++ _o240.d += _const[7]; \ +++ _n240.d += _const[6]; \ +++ _m240.d += _const[5]; \ +++ _l240.d += _const[4]; \ +++ if (_s240.d != 0.0) _y240 = 1; \ +++ if (_r240.d != 0.0) _y240 = 1; \ +++ if (_q240.d != 0.0) _y240 = 1; \ +++ if (_p240.d != 0.0) _y240 = 1; \ +++ _t240 = (DItype)_k240; \ +++ _u240 = _l240.i; \ +++ _v240 = _m240.i; \ +++ _w240 = _n240.i; \ +++ _x240 = _o240.i; \ +++ R##_f1 = (_t240 << (128 - (wfracbits - 1))) \ +++ | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)); \ +++ R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \ +++ | ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \ +++ | ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \ +++ | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \ +++ | _y240; \ +++ resetfe; \ +++ } while (0) +++ +++/* +++ * Division algorithms: +++ */ +++ +++#define _FP_DIV_MEAT_2_udiv(fs, R, X, Y) \ +++ do { \ +++ _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \ +++ if (_FP_FRAC_GT_2(X, Y)) \ +++ { \ +++ _n_f2 = X##_f1 >> 1; \ +++ _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \ +++ _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \ +++ } \ +++ else \ +++ { \ +++ R##_e--; \ +++ _n_f2 = X##_f1; \ +++ _n_f1 = X##_f0; \ +++ _n_f0 = 0; \ +++ } \ +++ \ +++ /* Normalize, i.e. make the most significant bit of the \ +++ denominator set. */ \ +++ _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \ +++ \ +++ udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \ +++ umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \ +++ _r_f0 = _n_f0; \ +++ if (_FP_FRAC_GT_2(_m, _r)) \ +++ { \ +++ R##_f1--; \ +++ _FP_FRAC_ADD_2(_r, Y, _r); \ +++ if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ +++ { \ +++ R##_f1--; \ +++ _FP_FRAC_ADD_2(_r, Y, _r); \ +++ } \ +++ } \ +++ _FP_FRAC_DEC_2(_r, _m); \ +++ \ +++ if (_r_f1 == Y##_f1) \ +++ { \ +++ /* This is a special case, not an optimization \ +++ (_r/Y##_f1 would not fit into UWtype). \ +++ As _r is guaranteed to be < Y, R##_f0 can be either \ +++ (UWtype)-1 or (UWtype)-2. But as we know what kind \ +++ of bits it is (sticky, guard, round), we don't care. \ +++ We also don't care what the reminder is, because the \ +++ guard bit will be set anyway. -jj */ \ +++ R##_f0 = -1; \ +++ } \ +++ else \ +++ { \ +++ udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \ +++ umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \ +++ _r_f0 = 0; \ +++ if (_FP_FRAC_GT_2(_m, _r)) \ +++ { \ +++ R##_f0--; \ +++ _FP_FRAC_ADD_2(_r, Y, _r); \ +++ if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ +++ { \ +++ R##_f0--; \ +++ _FP_FRAC_ADD_2(_r, Y, _r); \ +++ } \ +++ } \ +++ if (!_FP_FRAC_EQ_2(_r, _m)) \ +++ R##_f0 |= _FP_WORK_STICKY; \ +++ } \ +++ } while (0) +++ +++ +++#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \ +++ do { \ +++ _FP_W_TYPE _x[4], _y[2], _z[4]; \ +++ _y[0] = Y##_f0; _y[1] = Y##_f1; \ +++ _x[0] = _x[3] = 0; \ +++ if (_FP_FRAC_GT_2(X, Y)) \ +++ { \ +++ R##_e++; \ +++ _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) | \ +++ X##_f1 >> (_FP_W_TYPE_SIZE - \ +++ (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \ +++ _x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \ +++ } \ +++ else \ +++ { \ +++ _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) | \ +++ X##_f1 >> (_FP_W_TYPE_SIZE - \ +++ (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \ +++ _x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \ +++ } \ +++ \ +++ (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \ +++ R##_f1 = _z[1]; \ +++ R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \ +++ } while (0) +++ +++ +++/* +++ * Square root algorithms: +++ * We have just one right now, maybe Newton approximation +++ * should be added for those machines where division is fast. +++ */ +++ +++#define _FP_SQRT_MEAT_2(R, S, T, X, q) \ +++ do { \ +++ while (q) \ +++ { \ +++ T##_f1 = S##_f1 + q; \ +++ if (T##_f1 <= X##_f1) \ +++ { \ +++ S##_f1 = T##_f1 + q; \ +++ X##_f1 -= T##_f1; \ +++ R##_f1 += q; \ +++ } \ +++ _FP_FRAC_SLL_2(X, 1); \ +++ q >>= 1; \ +++ } \ +++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ +++ while (q != _FP_WORK_ROUND) \ +++ { \ +++ T##_f0 = S##_f0 + q; \ +++ T##_f1 = S##_f1; \ +++ if (T##_f1 < X##_f1 || \ +++ (T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \ +++ { \ +++ S##_f0 = T##_f0 + q; \ +++ S##_f1 += (T##_f0 > S##_f0); \ +++ _FP_FRAC_DEC_2(X, T); \ +++ R##_f0 += q; \ +++ } \ +++ _FP_FRAC_SLL_2(X, 1); \ +++ q >>= 1; \ +++ } \ +++ if (X##_f0 | X##_f1) \ +++ { \ +++ if (S##_f1 < X##_f1 || \ +++ (S##_f1 == X##_f1 && S##_f0 < X##_f0)) \ +++ R##_f0 |= _FP_WORK_ROUND; \ +++ R##_f0 |= _FP_WORK_STICKY; \ +++ } \ +++ } while (0) +++ +++ +++/* +++ * Assembly/disassembly for converting to/from integral types. +++ * No shifting or overflow handled here. +++ */ +++ +++#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \ +++(void)((rsize <= _FP_W_TYPE_SIZE) \ +++ ? ({ r = X##_f0; }) \ +++ : ({ \ +++ r = X##_f1; \ +++ r <<= _FP_W_TYPE_SIZE; \ +++ r += X##_f0; \ +++ })) +++ +++#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \ +++ do { \ +++ X##_f0 = r; \ +++ X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ +++ } while (0) +++ +++/* +++ * Convert FP values between word sizes +++ */ +++ +++#define _FP_FRAC_COPY_1_2(D, S) (D##_f = S##_f0) +++ +++#define _FP_FRAC_COPY_2_1(D, S) ((D##_f0 = S##_f), (D##_f1 = 0)) +++ +++#define _FP_FRAC_COPY_2_2(D,S) _FP_FRAC_COPY_2(D,S) ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-4.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-4.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-4.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-4.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,688 @@ +++/* Software floating-point emulation. +++ Basic four-word fraction declaration and manipulation. +++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz), +++ David S. Miller (davem@redhat.com) and +++ Peter Maydell (pmaydell@chiark.greenend.org.uk). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4] +++#define _FP_FRAC_COPY_4(D,S) \ +++ (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \ +++ D##_f[2] = S##_f[2], D##_f[3] = S##_f[3]) +++#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I) +++#define _FP_FRAC_HIGH_4(X) (X##_f[3]) +++#define _FP_FRAC_LOW_4(X) (X##_f[0]) +++#define _FP_FRAC_WORD_4(X,w) (X##_f[w]) +++ +++#define _FP_FRAC_SLL_4(X,N) \ +++ do { \ +++ _FP_I_TYPE _up, _down, _skip, _i; \ +++ _skip = (N) / _FP_W_TYPE_SIZE; \ +++ _up = (N) % _FP_W_TYPE_SIZE; \ +++ _down = _FP_W_TYPE_SIZE - _up; \ +++ if (!_up) \ +++ for (_i = 3; _i >= _skip; --_i) \ +++ X##_f[_i] = X##_f[_i-_skip]; \ +++ else \ +++ { \ +++ for (_i = 3; _i > _skip; --_i) \ +++ X##_f[_i] = X##_f[_i-_skip] << _up \ +++ | X##_f[_i-_skip-1] >> _down; \ +++ X##_f[_i--] = X##_f[0] << _up; \ +++ } \ +++ for (; _i >= 0; --_i) \ +++ X##_f[_i] = 0; \ +++ } while (0) +++ +++/* This one was broken too */ +++#define _FP_FRAC_SRL_4(X,N) \ +++ do { \ +++ _FP_I_TYPE _up, _down, _skip, _i; \ +++ _skip = (N) / _FP_W_TYPE_SIZE; \ +++ _down = (N) % _FP_W_TYPE_SIZE; \ +++ _up = _FP_W_TYPE_SIZE - _down; \ +++ if (!_down) \ +++ for (_i = 0; _i <= 3-_skip; ++_i) \ +++ X##_f[_i] = X##_f[_i+_skip]; \ +++ else \ +++ { \ +++ for (_i = 0; _i < 3-_skip; ++_i) \ +++ X##_f[_i] = X##_f[_i+_skip] >> _down \ +++ | X##_f[_i+_skip+1] << _up; \ +++ X##_f[_i++] = X##_f[3] >> _down; \ +++ } \ +++ for (; _i < 4; ++_i) \ +++ X##_f[_i] = 0; \ +++ } while (0) +++ +++ +++/* Right shift with sticky-lsb. +++ * What this actually means is that we do a standard right-shift, +++ * but that if any of the bits that fall off the right hand side +++ * were one then we always set the LSbit. +++ */ +++#define _FP_FRAC_SRST_4(X,S,N,size) \ +++ do { \ +++ _FP_I_TYPE _up, _down, _skip, _i; \ +++ _FP_W_TYPE _s; \ +++ _skip = (N) / _FP_W_TYPE_SIZE; \ +++ _down = (N) % _FP_W_TYPE_SIZE; \ +++ _up = _FP_W_TYPE_SIZE - _down; \ +++ for (_s = _i = 0; _i < _skip; ++_i) \ +++ _s |= X##_f[_i]; \ +++ if (!_down) \ +++ for (_i = 0; _i <= 3-_skip; ++_i) \ +++ X##_f[_i] = X##_f[_i+_skip]; \ +++ else \ +++ { \ +++ _s |= X##_f[_i] << _up; \ +++ for (_i = 0; _i < 3-_skip; ++_i) \ +++ X##_f[_i] = X##_f[_i+_skip] >> _down \ +++ | X##_f[_i+_skip+1] << _up; \ +++ X##_f[_i++] = X##_f[3] >> _down; \ +++ } \ +++ for (; _i < 4; ++_i) \ +++ X##_f[_i] = 0; \ +++ S = (_s != 0); \ +++ } while (0) +++ +++#define _FP_FRAC_SRS_4(X,N,size) \ +++ do { \ +++ int _sticky; \ +++ _FP_FRAC_SRST_4(X, _sticky, N, size); \ +++ X##_f[0] |= _sticky; \ +++ } while (0) +++ +++#define _FP_FRAC_ADD_4(R,X,Y) \ +++ __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ +++ X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ +++ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) +++ +++#define _FP_FRAC_SUB_4(R,X,Y) \ +++ __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ +++ X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ +++ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) +++ +++#define _FP_FRAC_DEC_4(X,Y) \ +++ __FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ +++ Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) +++ +++#define _FP_FRAC_ADDI_4(X,I) \ +++ __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I) +++ +++#define _FP_ZEROFRAC_4 0,0,0,0 +++#define _FP_MINFRAC_4 0,0,0,1 +++#define _FP_MAXFRAC_4 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) +++ +++#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0) +++#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0) +++#define _FP_FRAC_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) +++#define _FP_FRAC_CLEAR_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) +++ +++#define _FP_FRAC_EQ_4(X,Y) \ +++ (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \ +++ && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3]) +++ +++#define _FP_FRAC_GT_4(X,Y) \ +++ (X##_f[3] > Y##_f[3] || \ +++ (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ +++ (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ +++ (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \ +++ )) \ +++ )) \ +++ ) +++ +++#define _FP_FRAC_GE_4(X,Y) \ +++ (X##_f[3] > Y##_f[3] || \ +++ (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ +++ (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ +++ (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \ +++ )) \ +++ )) \ +++ ) +++ +++ +++#define _FP_FRAC_CLZ_4(R,X) \ +++ do { \ +++ if (X##_f[3]) \ +++ { \ +++ __FP_CLZ(R,X##_f[3]); \ +++ } \ +++ else if (X##_f[2]) \ +++ { \ +++ __FP_CLZ(R,X##_f[2]); \ +++ R += _FP_W_TYPE_SIZE; \ +++ } \ +++ else if (X##_f[1]) \ +++ { \ +++ __FP_CLZ(R,X##_f[1]); \ +++ R += _FP_W_TYPE_SIZE*2; \ +++ } \ +++ else \ +++ { \ +++ __FP_CLZ(R,X##_f[0]); \ +++ R += _FP_W_TYPE_SIZE*3; \ +++ } \ +++ } while(0) +++ +++ +++#define _FP_UNPACK_RAW_4(fs, X, val) \ +++ do { \ +++ union _FP_UNION_##fs _flo; _flo.flt = (val); \ +++ X##_f[0] = _flo.bits.frac0; \ +++ X##_f[1] = _flo.bits.frac1; \ +++ X##_f[2] = _flo.bits.frac2; \ +++ X##_f[3] = _flo.bits.frac3; \ +++ X##_e = _flo.bits.exp; \ +++ X##_s = _flo.bits.sign; \ +++ } while (0) +++ +++#define _FP_UNPACK_RAW_4_P(fs, X, val) \ +++ do { \ +++ union _FP_UNION_##fs *_flo = \ +++ (union _FP_UNION_##fs *)(val); \ +++ \ +++ X##_f[0] = _flo->bits.frac0; \ +++ X##_f[1] = _flo->bits.frac1; \ +++ X##_f[2] = _flo->bits.frac2; \ +++ X##_f[3] = _flo->bits.frac3; \ +++ X##_e = _flo->bits.exp; \ +++ X##_s = _flo->bits.sign; \ +++ } while (0) +++ +++#define _FP_PACK_RAW_4(fs, val, X) \ +++ do { \ +++ union _FP_UNION_##fs _flo; \ +++ _flo.bits.frac0 = X##_f[0]; \ +++ _flo.bits.frac1 = X##_f[1]; \ +++ _flo.bits.frac2 = X##_f[2]; \ +++ _flo.bits.frac3 = X##_f[3]; \ +++ _flo.bits.exp = X##_e; \ +++ _flo.bits.sign = X##_s; \ +++ (val) = _flo.flt; \ +++ } while (0) +++ +++#define _FP_PACK_RAW_4_P(fs, val, X) \ +++ do { \ +++ union _FP_UNION_##fs *_flo = \ +++ (union _FP_UNION_##fs *)(val); \ +++ \ +++ _flo->bits.frac0 = X##_f[0]; \ +++ _flo->bits.frac1 = X##_f[1]; \ +++ _flo->bits.frac2 = X##_f[2]; \ +++ _flo->bits.frac3 = X##_f[3]; \ +++ _flo->bits.exp = X##_e; \ +++ _flo->bits.sign = X##_s; \ +++ } while (0) +++ +++/* +++ * Multiplication algorithms: +++ */ +++ +++/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ +++ +++#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \ +++ do { \ +++ _FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ +++ _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f); \ +++ \ +++ doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \ +++ doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \ +++ doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \ +++ doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \ +++ doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \ +++ doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ +++ _FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0, \ +++ 0,0,_FP_FRAC_WORD_8(_z,1)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ +++ _FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0, \ +++ _FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ +++ _FP_FRAC_WORD_8(_z,1)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ +++ _FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0, \ +++ 0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ +++ _FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0, \ +++ _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ +++ _FP_FRAC_WORD_8(_z,2)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ +++ _FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0, \ +++ _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ +++ _FP_FRAC_WORD_8(_z,2)); \ +++ doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \ +++ doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \ +++ doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \ +++ doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ +++ _FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0, \ +++ 0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ +++ _FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0, \ +++ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ +++ _FP_FRAC_WORD_8(_z,3)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ +++ _FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0, \ +++ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ +++ _FP_FRAC_WORD_8(_z,3)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ +++ _FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0, \ +++ _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ +++ _FP_FRAC_WORD_8(_z,3)); \ +++ doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \ +++ doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \ +++ doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \ +++ doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \ +++ doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ +++ _FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0, \ +++ 0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ +++ _FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0, \ +++ _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ +++ _FP_FRAC_WORD_8(_z,4)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ +++ _FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0, \ +++ _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ +++ _FP_FRAC_WORD_8(_z,4)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ +++ _FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0, \ +++ 0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5)); \ +++ __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ +++ _FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0, \ +++ _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ +++ _FP_FRAC_WORD_8(_z,5)); \ +++ doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \ +++ __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ +++ _b_f1,_b_f0, \ +++ _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6)); \ +++ \ +++ /* Normalize since we know where the msb of the multiplicands \ +++ were (bit B), we know that the msb of the of the product is \ +++ at either 2B or 2B-1. */ \ +++ _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ +++ __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ +++ _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ +++ } while (0) +++ +++#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \ +++ do { \ +++ _FP_FRAC_DECL_8(_z); \ +++ \ +++ mpn_mul_n(_z_f, _x_f, _y_f, 4); \ +++ \ +++ /* Normalize since we know where the msb of the multiplicands \ +++ were (bit B), we know that the msb of the of the product is \ +++ at either 2B or 2B-1. */ \ +++ _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ +++ __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ +++ _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ +++ } while (0) +++ +++/* +++ * Helper utility for _FP_DIV_MEAT_4_udiv: +++ * pppp = m * nnn +++ */ +++#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \ +++ do { \ +++ UWtype _t; \ +++ umul_ppmm(p1,p0,m,n0); \ +++ umul_ppmm(p2,_t,m,n1); \ +++ __FP_FRAC_ADDI_2(p2,p1,_t); \ +++ umul_ppmm(p3,_t,m,n2); \ +++ __FP_FRAC_ADDI_2(p3,p2,_t); \ +++ } while (0) +++ +++/* +++ * Division algorithms: +++ */ +++ +++#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \ +++ do { \ +++ int _i; \ +++ _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \ +++ _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \ +++ if (_FP_FRAC_GT_4(X, Y)) \ +++ { \ +++ _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \ +++ _FP_FRAC_SRL_4(X, 1); \ +++ } \ +++ else \ +++ R##_e--; \ +++ \ +++ /* Normalize, i.e. make the most significant bit of the \ +++ denominator set. */ \ +++ _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \ +++ \ +++ for (_i = 3; ; _i--) \ +++ { \ +++ if (X##_f[3] == Y##_f[3]) \ +++ { \ +++ /* This is a special case, not an optimization \ +++ (X##_f[3]/Y##_f[3] would not fit into UWtype). \ +++ As X## is guaranteed to be < Y, R##_f[_i] can be either \ +++ (UWtype)-1 or (UWtype)-2. */ \ +++ R##_f[_i] = -1; \ +++ if (!_i) \ +++ break; \ +++ __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ +++ Y##_f[2], Y##_f[1], Y##_f[0], 0, \ +++ X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \ +++ _FP_FRAC_SUB_4(X, Y, X); \ +++ if (X##_f[3] > Y##_f[3]) \ +++ { \ +++ R##_f[_i] = -2; \ +++ _FP_FRAC_ADD_4(X, Y, X); \ +++ } \ +++ } \ +++ else \ +++ { \ +++ udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \ +++ umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \ +++ R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \ +++ X##_f[2] = X##_f[1]; \ +++ X##_f[1] = X##_f[0]; \ +++ X##_f[0] = _n_f[_i]; \ +++ if (_FP_FRAC_GT_4(_m, X)) \ +++ { \ +++ R##_f[_i]--; \ +++ _FP_FRAC_ADD_4(X, Y, X); \ +++ if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \ +++ { \ +++ R##_f[_i]--; \ +++ _FP_FRAC_ADD_4(X, Y, X); \ +++ } \ +++ } \ +++ _FP_FRAC_DEC_4(X, _m); \ +++ if (!_i) \ +++ { \ +++ if (!_FP_FRAC_EQ_4(X, _m)) \ +++ R##_f[0] |= _FP_WORK_STICKY; \ +++ break; \ +++ } \ +++ } \ +++ } \ +++ } while (0) +++ +++ +++/* +++ * Square root algorithms: +++ * We have just one right now, maybe Newton approximation +++ * should be added for those machines where division is fast. +++ */ +++ +++#define _FP_SQRT_MEAT_4(R, S, T, X, q) \ +++ do { \ +++ while (q) \ +++ { \ +++ T##_f[3] = S##_f[3] + q; \ +++ if (T##_f[3] <= X##_f[3]) \ +++ { \ +++ S##_f[3] = T##_f[3] + q; \ +++ X##_f[3] -= T##_f[3]; \ +++ R##_f[3] += q; \ +++ } \ +++ _FP_FRAC_SLL_4(X, 1); \ +++ q >>= 1; \ +++ } \ +++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ +++ while (q) \ +++ { \ +++ T##_f[2] = S##_f[2] + q; \ +++ T##_f[3] = S##_f[3]; \ +++ if (T##_f[3] < X##_f[3] || \ +++ (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \ +++ { \ +++ S##_f[2] = T##_f[2] + q; \ +++ S##_f[3] += (T##_f[2] > S##_f[2]); \ +++ __FP_FRAC_DEC_2(X##_f[3], X##_f[2], \ +++ T##_f[3], T##_f[2]); \ +++ R##_f[2] += q; \ +++ } \ +++ _FP_FRAC_SLL_4(X, 1); \ +++ q >>= 1; \ +++ } \ +++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ +++ while (q) \ +++ { \ +++ T##_f[1] = S##_f[1] + q; \ +++ T##_f[2] = S##_f[2]; \ +++ T##_f[3] = S##_f[3]; \ +++ if (T##_f[3] < X##_f[3] || \ +++ (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \ +++ (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \ +++ { \ +++ S##_f[1] = T##_f[1] + q; \ +++ S##_f[2] += (T##_f[1] > S##_f[1]); \ +++ S##_f[3] += (T##_f[2] > S##_f[2]); \ +++ __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \ +++ T##_f[3], T##_f[2], T##_f[1]); \ +++ R##_f[1] += q; \ +++ } \ +++ _FP_FRAC_SLL_4(X, 1); \ +++ q >>= 1; \ +++ } \ +++ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ +++ while (q != _FP_WORK_ROUND) \ +++ { \ +++ T##_f[0] = S##_f[0] + q; \ +++ T##_f[1] = S##_f[1]; \ +++ T##_f[2] = S##_f[2]; \ +++ T##_f[3] = S##_f[3]; \ +++ if (_FP_FRAC_GE_4(X,T)) \ +++ { \ +++ S##_f[0] = T##_f[0] + q; \ +++ S##_f[1] += (T##_f[0] > S##_f[0]); \ +++ S##_f[2] += (T##_f[1] > S##_f[1]); \ +++ S##_f[3] += (T##_f[2] > S##_f[2]); \ +++ _FP_FRAC_DEC_4(X, T); \ +++ R##_f[0] += q; \ +++ } \ +++ _FP_FRAC_SLL_4(X, 1); \ +++ q >>= 1; \ +++ } \ +++ if (!_FP_FRAC_ZEROP_4(X)) \ +++ { \ +++ if (_FP_FRAC_GT_4(X,S)) \ +++ R##_f[0] |= _FP_WORK_ROUND; \ +++ R##_f[0] |= _FP_WORK_STICKY; \ +++ } \ +++ } while (0) +++ +++ +++/* +++ * Internals +++ */ +++ +++#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \ +++ (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0) +++ +++#ifndef __FP_FRAC_ADD_3 +++#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ +++ do { \ +++ _FP_W_TYPE _c1, _c2; \ +++ r0 = x0 + y0; \ +++ _c1 = r0 < x0; \ +++ r1 = x1 + y1; \ +++ _c2 = r1 < x1; \ +++ r1 += _c1; \ +++ _c2 |= r1 < _c1; \ +++ r2 = x2 + y2 + _c2; \ +++ } while (0) +++#endif +++ +++#ifndef __FP_FRAC_ADD_4 +++#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ +++ do { \ +++ _FP_W_TYPE _c1, _c2, _c3; \ +++ r0 = x0 + y0; \ +++ _c1 = r0 < x0; \ +++ r1 = x1 + y1; \ +++ _c2 = r1 < x1; \ +++ r1 += _c1; \ +++ _c2 |= r1 < _c1; \ +++ r2 = x2 + y2; \ +++ _c3 = r2 < x2; \ +++ r2 += _c2; \ +++ _c3 |= r2 < _c2; \ +++ r3 = x3 + y3 + _c3; \ +++ } while (0) +++#endif +++ +++#ifndef __FP_FRAC_SUB_3 +++#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ +++ do { \ +++ _FP_W_TYPE _c1, _c2; \ +++ r0 = x0 - y0; \ +++ _c1 = r0 > x0; \ +++ r1 = x1 - y1; \ +++ _c2 = r1 > x1; \ +++ r1 -= _c1; \ +++ _c2 |= _c1 && (y1 == x1); \ +++ r2 = x2 - y2 - _c2; \ +++ } while (0) +++#endif +++ +++#ifndef __FP_FRAC_SUB_4 +++#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ +++ do { \ +++ _FP_W_TYPE _c1, _c2, _c3; \ +++ r0 = x0 - y0; \ +++ _c1 = r0 > x0; \ +++ r1 = x1 - y1; \ +++ _c2 = r1 > x1; \ +++ r1 -= _c1; \ +++ _c2 |= _c1 && (y1 == x1); \ +++ r2 = x2 - y2; \ +++ _c3 = r2 > x2; \ +++ r2 -= _c2; \ +++ _c3 |= _c2 && (y2 == x2); \ +++ r3 = x3 - y3 - _c3; \ +++ } while (0) +++#endif +++ +++#ifndef __FP_FRAC_DEC_3 +++#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \ +++ do { \ +++ UWtype _t0, _t1, _t2; \ +++ _t0 = x0, _t1 = x1, _t2 = x2; \ +++ __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \ +++ } while (0) +++#endif +++ +++#ifndef __FP_FRAC_DEC_4 +++#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \ +++ do { \ +++ UWtype _t0, _t1, _t2, _t3; \ +++ _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \ +++ __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \ +++ } while (0) +++#endif +++ +++#ifndef __FP_FRAC_ADDI_4 +++#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ +++ do { \ +++ UWtype _t; \ +++ _t = ((x0 += i) < i); \ +++ x1 += _t; _t = (x1 < _t); \ +++ x2 += _t; _t = (x2 < _t); \ +++ x3 += _t; \ +++ } while (0) +++#endif +++ +++/* Convert FP values between word sizes. This appears to be more +++ * complicated than I'd have expected it to be, so these might be +++ * wrong... These macros are in any case somewhat bogus because they +++ * use information about what various FRAC_n variables look like +++ * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do +++ * the ones in op-2.h and op-1.h. +++ */ +++#define _FP_FRAC_COPY_1_4(D, S) (D##_f = S##_f[0]) +++ +++#define _FP_FRAC_COPY_2_4(D, S) \ +++do { \ +++ D##_f0 = S##_f[0]; \ +++ D##_f1 = S##_f[1]; \ +++} while (0) +++ +++/* Assembly/disassembly for converting to/from integral types. +++ * No shifting or overflow handled here. +++ */ +++/* Put the FP value X into r, which is an integer of size rsize. */ +++#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \ +++ do { \ +++ if (rsize <= _FP_W_TYPE_SIZE) \ +++ r = X##_f[0]; \ +++ else if (rsize <= 2*_FP_W_TYPE_SIZE) \ +++ { \ +++ r = X##_f[1]; \ +++ r <<= _FP_W_TYPE_SIZE; \ +++ r += X##_f[0]; \ +++ } \ +++ else \ +++ { \ +++ /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ +++ /* and int == 4words as a single case. */ \ +++ r = X##_f[3]; \ +++ r <<= _FP_W_TYPE_SIZE; \ +++ r += X##_f[2]; \ +++ r <<= _FP_W_TYPE_SIZE; \ +++ r += X##_f[1]; \ +++ r <<= _FP_W_TYPE_SIZE; \ +++ r += X##_f[0]; \ +++ } \ +++ } while (0) +++ +++/* "No disassemble Number Five!" */ +++/* move an integer of size rsize into X's fractional part. We rely on +++ * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid +++ * having to mask the values we store into it. +++ */ +++#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \ +++ do { \ +++ X##_f[0] = r; \ +++ X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ +++ X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ +++ X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ +++ } while (0); +++ +++#define _FP_FRAC_COPY_4_1(D, S) \ +++do { \ +++ D##_f[0] = S##_f; \ +++ D##_f[1] = D##_f[2] = D##_f[3] = 0; \ +++} while (0) +++ +++#define _FP_FRAC_COPY_4_2(D, S) \ +++do { \ +++ D##_f[0] = S##_f0; \ +++ D##_f[1] = S##_f1; \ +++ D##_f[2] = D##_f[3] = 0; \ +++} while (0) +++ +++#define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S) ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-8.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-8.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-8.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-8.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,111 @@ +++/* Software floating-point emulation. +++ Basic eight-word fraction declaration and manipulation. +++ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz) and +++ Peter Maydell (pmaydell@chiark.greenend.org.uk). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++/* We need just a few things from here for op-4, if we ever need some +++ other macros, they can be added. */ +++#define _FP_FRAC_DECL_8(X) _FP_W_TYPE X##_f[8] +++#define _FP_FRAC_HIGH_8(X) (X##_f[7]) +++#define _FP_FRAC_LOW_8(X) (X##_f[0]) +++#define _FP_FRAC_WORD_8(X,w) (X##_f[w]) +++ +++#define _FP_FRAC_SLL_8(X,N) \ +++ do { \ +++ _FP_I_TYPE _up, _down, _skip, _i; \ +++ _skip = (N) / _FP_W_TYPE_SIZE; \ +++ _up = (N) % _FP_W_TYPE_SIZE; \ +++ _down = _FP_W_TYPE_SIZE - _up; \ +++ if (!_up) \ +++ for (_i = 7; _i >= _skip; --_i) \ +++ X##_f[_i] = X##_f[_i-_skip]; \ +++ else \ +++ { \ +++ for (_i = 7; _i > _skip; --_i) \ +++ X##_f[_i] = X##_f[_i-_skip] << _up \ +++ | X##_f[_i-_skip-1] >> _down; \ +++ X##_f[_i--] = X##_f[0] << _up; \ +++ } \ +++ for (; _i >= 0; --_i) \ +++ X##_f[_i] = 0; \ +++ } while (0) +++ +++#define _FP_FRAC_SRL_8(X,N) \ +++ do { \ +++ _FP_I_TYPE _up, _down, _skip, _i; \ +++ _skip = (N) / _FP_W_TYPE_SIZE; \ +++ _down = (N) % _FP_W_TYPE_SIZE; \ +++ _up = _FP_W_TYPE_SIZE - _down; \ +++ if (!_down) \ +++ for (_i = 0; _i <= 7-_skip; ++_i) \ +++ X##_f[_i] = X##_f[_i+_skip]; \ +++ else \ +++ { \ +++ for (_i = 0; _i < 7-_skip; ++_i) \ +++ X##_f[_i] = X##_f[_i+_skip] >> _down \ +++ | X##_f[_i+_skip+1] << _up; \ +++ X##_f[_i++] = X##_f[7] >> _down; \ +++ } \ +++ for (; _i < 8; ++_i) \ +++ X##_f[_i] = 0; \ +++ } while (0) +++ +++ +++/* Right shift with sticky-lsb. +++ * What this actually means is that we do a standard right-shift, +++ * but that if any of the bits that fall off the right hand side +++ * were one then we always set the LSbit. +++ */ +++#define _FP_FRAC_SRS_8(X,N,size) \ +++ do { \ +++ _FP_I_TYPE _up, _down, _skip, _i; \ +++ _FP_W_TYPE _s; \ +++ _skip = (N) / _FP_W_TYPE_SIZE; \ +++ _down = (N) % _FP_W_TYPE_SIZE; \ +++ _up = _FP_W_TYPE_SIZE - _down; \ +++ for (_s = _i = 0; _i < _skip; ++_i) \ +++ _s |= X##_f[_i]; \ +++ if (!_down) \ +++ for (_i = 0; _i <= 7-_skip; ++_i) \ +++ X##_f[_i] = X##_f[_i+_skip]; \ +++ else \ +++ { \ +++ _s |= X##_f[_i] << _up; \ +++ for (_i = 0; _i < 7-_skip; ++_i) \ +++ X##_f[_i] = X##_f[_i+_skip] >> _down \ +++ | X##_f[_i+_skip+1] << _up; \ +++ X##_f[_i++] = X##_f[7] >> _down; \ +++ } \ +++ for (; _i < 8; ++_i) \ +++ X##_f[_i] = 0; \ +++ /* don't fix the LSB until the very end when we're sure f[0] is stable */ \ +++ X##_f[0] |= (_s != 0); \ +++ } while (0) +++ ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-common.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-common.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/op-common.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/op-common.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,1359 @@ +++/* Software floating-point emulation. Common operations. +++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz), +++ David S. Miller (davem@redhat.com) and +++ Peter Maydell (pmaydell@chiark.greenend.org.uk). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++#define _FP_DECL(wc, X) \ +++ _FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e; \ +++ _FP_FRAC_DECL_##wc(X) +++ +++/* +++ * Finish truely unpacking a native fp value by classifying the kind +++ * of fp value and normalizing both the exponent and the fraction. +++ */ +++ +++#define _FP_UNPACK_CANONICAL(fs, wc, X) \ +++do { \ +++ switch (X##_e) \ +++ { \ +++ default: \ +++ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ +++ _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ +++ X##_e -= _FP_EXPBIAS_##fs; \ +++ X##_c = FP_CLS_NORMAL; \ +++ break; \ +++ \ +++ case 0: \ +++ if (_FP_FRAC_ZEROP_##wc(X)) \ +++ X##_c = FP_CLS_ZERO; \ +++ else \ +++ { \ +++ /* a denormalized number */ \ +++ _FP_I_TYPE _shift; \ +++ _FP_FRAC_CLZ_##wc(_shift, X); \ +++ _shift -= _FP_FRACXBITS_##fs; \ +++ _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ +++ X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ +++ X##_c = FP_CLS_NORMAL; \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ } \ +++ break; \ +++ \ +++ case _FP_EXPMAX_##fs: \ +++ if (_FP_FRAC_ZEROP_##wc(X)) \ +++ X##_c = FP_CLS_INF; \ +++ else \ +++ { \ +++ X##_c = FP_CLS_NAN; \ +++ /* Check for signaling NaN */ \ +++ if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++ } \ +++ break; \ +++ } \ +++} while (0) +++ +++/* Finish unpacking an fp value in semi-raw mode: the mantissa is +++ shifted by _FP_WORKBITS but the implicit MSB is not inserted and +++ other classification is not done. */ +++#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS) +++ +++/* A semi-raw value has overflowed to infinity. Adjust the mantissa +++ and exponent appropriately. */ +++#define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \ +++do { \ +++ if (FP_ROUNDMODE == FP_RND_NEAREST \ +++ || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ +++ || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ +++ { \ +++ X##_e = _FP_EXPMAX_##fs; \ +++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ +++ } \ +++ else \ +++ { \ +++ X##_e = _FP_EXPMAX_##fs - 1; \ +++ _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ +++ } \ +++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ +++ FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ +++} while (0) +++ +++/* Check for a semi-raw value being a signaling NaN and raise the +++ invalid exception if so. */ +++#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ +++do { \ +++ if (X##_e == _FP_EXPMAX_##fs \ +++ && !_FP_FRAC_ZEROP_##wc(X) \ +++ && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++} while (0) +++ +++/* Choose a NaN result from an operation on two semi-raw NaN +++ values. */ +++#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \ +++do { \ +++ /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ +++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ +++ _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \ +++ _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \ +++ _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ +++} while (0) +++ +++/* Test whether a biased exponent is normal (not zero or maximum). */ +++#define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1) +++ +++/* Prepare to pack an fp value in semi-raw mode: the mantissa is +++ rounded and shifted right, with the rounding possibly increasing +++ the exponent (including changing a finite value to infinity). */ +++#define _FP_PACK_SEMIRAW(fs, wc, X) \ +++do { \ +++ _FP_ROUND(wc, X); \ +++ if (_FP_FRAC_HIGH_##fs(X) \ +++ & (_FP_OVERFLOW_##fs >> 1)) \ +++ { \ +++ _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \ +++ X##_e++; \ +++ if (X##_e == _FP_EXPMAX_##fs) \ +++ _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ +++ } \ +++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ +++ if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \ +++ { \ +++ if (X##_e == 0) \ +++ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ +++ else \ +++ { \ +++ if (!_FP_KEEPNANFRACP) \ +++ { \ +++ _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ +++ X##_s = _FP_NANSIGN_##fs; \ +++ } \ +++ else \ +++ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ +++ } \ +++ } \ +++} while (0) +++ +++/* +++ * Before packing the bits back into the native fp result, take care +++ * of such mundane things as rounding and overflow. Also, for some +++ * kinds of fp values, the original parts may not have been fully +++ * extracted -- but that is ok, we can regenerate them now. +++ */ +++ +++#define _FP_PACK_CANONICAL(fs, wc, X) \ +++do { \ +++ switch (X##_c) \ +++ { \ +++ case FP_CLS_NORMAL: \ +++ X##_e += _FP_EXPBIAS_##fs; \ +++ if (X##_e > 0) \ +++ { \ +++ _FP_ROUND(wc, X); \ +++ if (_FP_FRAC_OVERP_##wc(fs, X)) \ +++ { \ +++ _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \ +++ X##_e++; \ +++ } \ +++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ +++ if (X##_e >= _FP_EXPMAX_##fs) \ +++ { \ +++ /* overflow */ \ +++ switch (FP_ROUNDMODE) \ +++ { \ +++ case FP_RND_NEAREST: \ +++ X##_c = FP_CLS_INF; \ +++ break; \ +++ case FP_RND_PINF: \ +++ if (!X##_s) X##_c = FP_CLS_INF; \ +++ break; \ +++ case FP_RND_MINF: \ +++ if (X##_s) X##_c = FP_CLS_INF; \ +++ break; \ +++ } \ +++ if (X##_c == FP_CLS_INF) \ +++ { \ +++ /* Overflow to infinity */ \ +++ X##_e = _FP_EXPMAX_##fs; \ +++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ +++ } \ +++ else \ +++ { \ +++ /* Overflow to maximum normal */ \ +++ X##_e = _FP_EXPMAX_##fs - 1; \ +++ _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ +++ } \ +++ FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ +++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ +++ } \ +++ } \ +++ else \ +++ { \ +++ /* we've got a denormalized number */ \ +++ X##_e = -X##_e + 1; \ +++ if (X##_e <= _FP_WFRACBITS_##fs) \ +++ { \ +++ _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ +++ _FP_ROUND(wc, X); \ +++ if (_FP_FRAC_HIGH_##fs(X) \ +++ & (_FP_OVERFLOW_##fs >> 1)) \ +++ { \ +++ X##_e = 1; \ +++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ +++ } \ +++ else \ +++ { \ +++ X##_e = 0; \ +++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ +++ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ +++ } \ +++ } \ +++ else \ +++ { \ +++ /* underflow to zero */ \ +++ X##_e = 0; \ +++ if (!_FP_FRAC_ZEROP_##wc(X)) \ +++ { \ +++ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ +++ _FP_ROUND(wc, X); \ +++ _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \ +++ } \ +++ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ +++ } \ +++ } \ +++ break; \ +++ \ +++ case FP_CLS_ZERO: \ +++ X##_e = 0; \ +++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ +++ break; \ +++ \ +++ case FP_CLS_INF: \ +++ X##_e = _FP_EXPMAX_##fs; \ +++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ +++ break; \ +++ \ +++ case FP_CLS_NAN: \ +++ X##_e = _FP_EXPMAX_##fs; \ +++ if (!_FP_KEEPNANFRACP) \ +++ { \ +++ _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ +++ X##_s = _FP_NANSIGN_##fs; \ +++ } \ +++ else \ +++ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ +++ break; \ +++ } \ +++} while (0) +++ +++/* This one accepts raw argument and not cooked, returns +++ * 1 if X is a signaling NaN. +++ */ +++#define _FP_ISSIGNAN(fs, wc, X) \ +++({ \ +++ int __ret = 0; \ +++ if (X##_e == _FP_EXPMAX_##fs) \ +++ { \ +++ if (!_FP_FRAC_ZEROP_##wc(X) \ +++ && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ +++ __ret = 1; \ +++ } \ +++ __ret; \ +++}) +++ +++ +++ +++ +++ +++/* Addition on semi-raw values. */ +++#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ +++do { \ +++ if (X##_s == Y##_s) \ +++ { \ +++ /* Addition. */ \ +++ R##_s = X##_s; \ +++ int ediff = X##_e - Y##_e; \ +++ if (ediff > 0) \ +++ { \ +++ R##_e = X##_e; \ +++ if (Y##_e == 0) \ +++ { \ +++ /* Y is zero or denormalized. */ \ +++ if (_FP_FRAC_ZEROP_##wc(Y)) \ +++ { \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ goto add_done; \ +++ } \ +++ else \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ ediff--; \ +++ if (ediff == 0) \ +++ { \ +++ _FP_FRAC_ADD_##wc(R, X, Y); \ +++ goto add3; \ +++ } \ +++ if (X##_e == _FP_EXPMAX_##fs) \ +++ { \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ goto add_done; \ +++ } \ +++ goto add1; \ +++ } \ +++ } \ +++ else if (X##_e == _FP_EXPMAX_##fs) \ +++ { \ +++ /* X is NaN or Inf, Y is normal. */ \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ goto add_done; \ +++ } \ +++ \ +++ /* Insert implicit MSB of Y. */ \ +++ _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ +++ \ +++ add1: \ +++ /* Shift the mantissa of Y to the right EDIFF steps; \ +++ remember to account later for the implicit MSB of X. */ \ +++ if (ediff <= _FP_WFRACBITS_##fs) \ +++ _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ +++ else if (!_FP_FRAC_ZEROP_##wc(Y)) \ +++ _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ +++ _FP_FRAC_ADD_##wc(R, X, Y); \ +++ } \ +++ else if (ediff < 0) \ +++ { \ +++ ediff = -ediff; \ +++ R##_e = Y##_e; \ +++ if (X##_e == 0) \ +++ { \ +++ /* X is zero or denormalized. */ \ +++ if (_FP_FRAC_ZEROP_##wc(X)) \ +++ { \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ goto add_done; \ +++ } \ +++ else \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ ediff--; \ +++ if (ediff == 0) \ +++ { \ +++ _FP_FRAC_ADD_##wc(R, Y, X); \ +++ goto add3; \ +++ } \ +++ if (Y##_e == _FP_EXPMAX_##fs) \ +++ { \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ goto add_done; \ +++ } \ +++ goto add2; \ +++ } \ +++ } \ +++ else if (Y##_e == _FP_EXPMAX_##fs) \ +++ { \ +++ /* Y is NaN or Inf, X is normal. */ \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ goto add_done; \ +++ } \ +++ \ +++ /* Insert implicit MSB of X. */ \ +++ _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ +++ \ +++ add2: \ +++ /* Shift the mantissa of X to the right EDIFF steps; \ +++ remember to account later for the implicit MSB of Y. */ \ +++ if (ediff <= _FP_WFRACBITS_##fs) \ +++ _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ +++ else if (!_FP_FRAC_ZEROP_##wc(X)) \ +++ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ +++ _FP_FRAC_ADD_##wc(R, Y, X); \ +++ } \ +++ else \ +++ { \ +++ /* ediff == 0. */ \ +++ if (!_FP_EXP_NORMAL(fs, wc, X)) \ +++ { \ +++ if (X##_e == 0) \ +++ { \ +++ /* X and Y are zero or denormalized. */ \ +++ R##_e = 0; \ +++ if (_FP_FRAC_ZEROP_##wc(X)) \ +++ { \ +++ if (!_FP_FRAC_ZEROP_##wc(Y)) \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ goto add_done; \ +++ } \ +++ else if (_FP_FRAC_ZEROP_##wc(Y)) \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ goto add_done; \ +++ } \ +++ else \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ _FP_FRAC_ADD_##wc(R, X, Y); \ +++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ +++ { \ +++ /* Normalized result. */ \ +++ _FP_FRAC_HIGH_##fs(R) \ +++ &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ +++ R##_e = 1; \ +++ } \ +++ goto add_done; \ +++ } \ +++ } \ +++ else \ +++ { \ +++ /* X and Y are NaN or Inf. */ \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ +++ R##_e = _FP_EXPMAX_##fs; \ +++ if (_FP_FRAC_ZEROP_##wc(X)) \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ else if (_FP_FRAC_ZEROP_##wc(Y)) \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ else \ +++ _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ +++ goto add_done; \ +++ } \ +++ } \ +++ /* The exponents of X and Y, both normal, are equal. The \ +++ implicit MSBs will always add to increase the \ +++ exponent. */ \ +++ _FP_FRAC_ADD_##wc(R, X, Y); \ +++ R##_e = X##_e + 1; \ +++ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ +++ if (R##_e == _FP_EXPMAX_##fs) \ +++ /* Overflow to infinity (depending on rounding mode). */ \ +++ _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ +++ goto add_done; \ +++ } \ +++ add3: \ +++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ +++ { \ +++ /* Overflow. */ \ +++ _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ +++ R##_e++; \ +++ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ +++ if (R##_e == _FP_EXPMAX_##fs) \ +++ /* Overflow to infinity (depending on rounding mode). */ \ +++ _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ +++ } \ +++ add_done: ; \ +++ } \ +++ else \ +++ { \ +++ /* Subtraction. */ \ +++ int ediff = X##_e - Y##_e; \ +++ if (ediff > 0) \ +++ { \ +++ R##_e = X##_e; \ +++ R##_s = X##_s; \ +++ if (Y##_e == 0) \ +++ { \ +++ /* Y is zero or denormalized. */ \ +++ if (_FP_FRAC_ZEROP_##wc(Y)) \ +++ { \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ goto sub_done; \ +++ } \ +++ else \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ ediff--; \ +++ if (ediff == 0) \ +++ { \ +++ _FP_FRAC_SUB_##wc(R, X, Y); \ +++ goto sub3; \ +++ } \ +++ if (X##_e == _FP_EXPMAX_##fs) \ +++ { \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ goto sub_done; \ +++ } \ +++ goto sub1; \ +++ } \ +++ } \ +++ else if (X##_e == _FP_EXPMAX_##fs) \ +++ { \ +++ /* X is NaN or Inf, Y is normal. */ \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ goto sub_done; \ +++ } \ +++ \ +++ /* Insert implicit MSB of Y. */ \ +++ _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ +++ \ +++ sub1: \ +++ /* Shift the mantissa of Y to the right EDIFF steps; \ +++ remember to account later for the implicit MSB of X. */ \ +++ if (ediff <= _FP_WFRACBITS_##fs) \ +++ _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ +++ else if (!_FP_FRAC_ZEROP_##wc(Y)) \ +++ _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ +++ _FP_FRAC_SUB_##wc(R, X, Y); \ +++ } \ +++ else if (ediff < 0) \ +++ { \ +++ ediff = -ediff; \ +++ R##_e = Y##_e; \ +++ R##_s = Y##_s; \ +++ if (X##_e == 0) \ +++ { \ +++ /* X is zero or denormalized. */ \ +++ if (_FP_FRAC_ZEROP_##wc(X)) \ +++ { \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ goto sub_done; \ +++ } \ +++ else \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ ediff--; \ +++ if (ediff == 0) \ +++ { \ +++ _FP_FRAC_SUB_##wc(R, Y, X); \ +++ goto sub3; \ +++ } \ +++ if (Y##_e == _FP_EXPMAX_##fs) \ +++ { \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ goto sub_done; \ +++ } \ +++ goto sub2; \ +++ } \ +++ } \ +++ else if (Y##_e == _FP_EXPMAX_##fs) \ +++ { \ +++ /* Y is NaN or Inf, X is normal. */ \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ goto sub_done; \ +++ } \ +++ \ +++ /* Insert implicit MSB of X. */ \ +++ _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ +++ \ +++ sub2: \ +++ /* Shift the mantissa of X to the right EDIFF steps; \ +++ remember to account later for the implicit MSB of Y. */ \ +++ if (ediff <= _FP_WFRACBITS_##fs) \ +++ _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ +++ else if (!_FP_FRAC_ZEROP_##wc(X)) \ +++ _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ +++ _FP_FRAC_SUB_##wc(R, Y, X); \ +++ } \ +++ else \ +++ { \ +++ /* ediff == 0. */ \ +++ if (!_FP_EXP_NORMAL(fs, wc, X)) \ +++ { \ +++ if (X##_e == 0) \ +++ { \ +++ /* X and Y are zero or denormalized. */ \ +++ R##_e = 0; \ +++ if (_FP_FRAC_ZEROP_##wc(X)) \ +++ { \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ if (_FP_FRAC_ZEROP_##wc(Y)) \ +++ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ +++ else \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ R##_s = Y##_s; \ +++ } \ +++ goto sub_done; \ +++ } \ +++ else if (_FP_FRAC_ZEROP_##wc(Y)) \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ R##_s = X##_s; \ +++ goto sub_done; \ +++ } \ +++ else \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ _FP_FRAC_SUB_##wc(R, X, Y); \ +++ R##_s = X##_s; \ +++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ +++ { \ +++ /* |X| < |Y|, negate result. */ \ +++ _FP_FRAC_SUB_##wc(R, Y, X); \ +++ R##_s = Y##_s; \ +++ } \ +++ else if (_FP_FRAC_ZEROP_##wc(R)) \ +++ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ +++ goto sub_done; \ +++ } \ +++ } \ +++ else \ +++ { \ +++ /* X and Y are NaN or Inf, of opposite signs. */ \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ +++ _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ +++ R##_e = _FP_EXPMAX_##fs; \ +++ if (_FP_FRAC_ZEROP_##wc(X)) \ +++ { \ +++ if (_FP_FRAC_ZEROP_##wc(Y)) \ +++ { \ +++ /* Inf - Inf. */ \ +++ R##_s = _FP_NANSIGN_##fs; \ +++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ +++ _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++ } \ +++ else \ +++ { \ +++ /* Inf - NaN. */ \ +++ R##_s = Y##_s; \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ } \ +++ } \ +++ else \ +++ { \ +++ if (_FP_FRAC_ZEROP_##wc(Y)) \ +++ { \ +++ /* NaN - Inf. */ \ +++ R##_s = X##_s; \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ } \ +++ else \ +++ { \ +++ /* NaN - NaN. */ \ +++ _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ +++ } \ +++ } \ +++ goto sub_done; \ +++ } \ +++ } \ +++ /* The exponents of X and Y, both normal, are equal. The \ +++ implicit MSBs cancel. */ \ +++ R##_e = X##_e; \ +++ _FP_FRAC_SUB_##wc(R, X, Y); \ +++ R##_s = X##_s; \ +++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ +++ { \ +++ /* |X| < |Y|, negate result. */ \ +++ _FP_FRAC_SUB_##wc(R, Y, X); \ +++ R##_s = Y##_s; \ +++ } \ +++ else if (_FP_FRAC_ZEROP_##wc(R)) \ +++ { \ +++ R##_e = 0; \ +++ R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ +++ goto sub_done; \ +++ } \ +++ goto norm; \ +++ } \ +++ sub3: \ +++ if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ +++ { \ +++ int diff; \ +++ /* Carry into most significant bit of larger one of X and Y, \ +++ canceling it; renormalize. */ \ +++ _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \ +++ norm: \ +++ _FP_FRAC_CLZ_##wc(diff, R); \ +++ diff -= _FP_WFRACXBITS_##fs; \ +++ _FP_FRAC_SLL_##wc(R, diff); \ +++ if (R##_e <= diff) \ +++ { \ +++ /* R is denormalized. */ \ +++ diff = diff - R##_e + 1; \ +++ _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \ +++ R##_e = 0; \ +++ } \ +++ else \ +++ { \ +++ R##_e -= diff; \ +++ _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ +++ } \ +++ } \ +++ sub_done: ; \ +++ } \ +++} while (0) +++ +++#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+') +++#define _FP_SUB(fs, wc, R, X, Y) \ +++ do { \ +++ if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \ +++ _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \ +++ } while (0) +++ +++ +++/* +++ * Main negation routine. FIXME -- when we care about setting exception +++ * bits reliably, this will not do. We should examine all of the fp classes. +++ */ +++ +++#define _FP_NEG(fs, wc, R, X) \ +++ do { \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ R##_c = X##_c; \ +++ R##_e = X##_e; \ +++ R##_s = 1 ^ X##_s; \ +++ } while (0) +++ +++ +++/* +++ * Main multiplication routine. The input values should be cooked. +++ */ +++ +++#define _FP_MUL(fs, wc, R, X, Y) \ +++do { \ +++ R##_s = X##_s ^ Y##_s; \ +++ switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ +++ { \ +++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ +++ R##_c = FP_CLS_NORMAL; \ +++ R##_e = X##_e + Y##_e + 1; \ +++ \ +++ _FP_MUL_MEAT_##fs(R,X,Y); \ +++ \ +++ if (_FP_FRAC_OVERP_##wc(fs, R)) \ +++ _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ +++ else \ +++ R##_e--; \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ +++ _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ +++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ +++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ +++ R##_s = X##_s; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ +++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ +++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ +++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ R##_c = X##_c; \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ +++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ +++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ +++ R##_s = Y##_s; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ +++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ R##_c = Y##_c; \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ +++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ +++ R##_s = _FP_NANSIGN_##fs; \ +++ R##_c = FP_CLS_NAN; \ +++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++ break; \ +++ \ +++ default: \ +++ abort(); \ +++ } \ +++} while (0) +++ +++ +++/* +++ * Main division routine. The input values should be cooked. +++ */ +++ +++#define _FP_DIV(fs, wc, R, X, Y) \ +++do { \ +++ R##_s = X##_s ^ Y##_s; \ +++ switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ +++ { \ +++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ +++ R##_c = FP_CLS_NORMAL; \ +++ R##_e = X##_e - Y##_e; \ +++ \ +++ _FP_DIV_MEAT_##fs(R,X,Y); \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ +++ _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ +++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ +++ case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ +++ R##_s = X##_s; \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ R##_c = X##_c; \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ +++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ +++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ +++ R##_s = Y##_s; \ +++ _FP_FRAC_COPY_##wc(R, Y); \ +++ R##_c = Y##_c; \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ +++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ +++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ +++ R##_c = FP_CLS_ZERO; \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ +++ FP_SET_EXCEPTION(FP_EX_DIVZERO); \ +++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ +++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ +++ R##_c = FP_CLS_INF; \ +++ break; \ +++ \ +++ case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ +++ case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ +++ R##_s = _FP_NANSIGN_##fs; \ +++ R##_c = FP_CLS_NAN; \ +++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++ break; \ +++ \ +++ default: \ +++ abort(); \ +++ } \ +++} while (0) +++ +++ +++/* +++ * Main differential comparison routine. The inputs should be raw not +++ * cooked. The return is -1,0,1 for normal values, 2 otherwise. +++ */ +++ +++#define _FP_CMP(fs, wc, ret, X, Y, un) \ +++ do { \ +++ /* NANs are unordered */ \ +++ if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ +++ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ +++ { \ +++ ret = un; \ +++ } \ +++ else \ +++ { \ +++ int __is_zero_x; \ +++ int __is_zero_y; \ +++ \ +++ __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ +++ __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ +++ \ +++ if (__is_zero_x && __is_zero_y) \ +++ ret = 0; \ +++ else if (__is_zero_x) \ +++ ret = Y##_s ? 1 : -1; \ +++ else if (__is_zero_y) \ +++ ret = X##_s ? -1 : 1; \ +++ else if (X##_s != Y##_s) \ +++ ret = X##_s ? -1 : 1; \ +++ else if (X##_e > Y##_e) \ +++ ret = X##_s ? -1 : 1; \ +++ else if (X##_e < Y##_e) \ +++ ret = X##_s ? 1 : -1; \ +++ else if (_FP_FRAC_GT_##wc(X, Y)) \ +++ ret = X##_s ? -1 : 1; \ +++ else if (_FP_FRAC_GT_##wc(Y, X)) \ +++ ret = X##_s ? 1 : -1; \ +++ else \ +++ ret = 0; \ +++ } \ +++ } while (0) +++ +++ +++/* Simplification for strict equality. */ +++ +++#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ +++ do { \ +++ /* NANs are unordered */ \ +++ if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ +++ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ +++ { \ +++ ret = 1; \ +++ } \ +++ else \ +++ { \ +++ ret = !(X##_e == Y##_e \ +++ && _FP_FRAC_EQ_##wc(X, Y) \ +++ && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \ +++ } \ +++ } while (0) +++ +++/* Version to test unordered. */ +++ +++#define _FP_CMP_UNORD(fs, wc, ret, X, Y) \ +++ do { \ +++ ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ +++ || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \ +++ } while (0) +++ +++/* +++ * Main square root routine. The input value should be cooked. +++ */ +++ +++#define _FP_SQRT(fs, wc, R, X) \ +++do { \ +++ _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ +++ _FP_W_TYPE q; \ +++ switch (X##_c) \ +++ { \ +++ case FP_CLS_NAN: \ +++ _FP_FRAC_COPY_##wc(R, X); \ +++ R##_s = X##_s; \ +++ R##_c = FP_CLS_NAN; \ +++ break; \ +++ case FP_CLS_INF: \ +++ if (X##_s) \ +++ { \ +++ R##_s = _FP_NANSIGN_##fs; \ +++ R##_c = FP_CLS_NAN; /* NAN */ \ +++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++ } \ +++ else \ +++ { \ +++ R##_s = 0; \ +++ R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ +++ } \ +++ break; \ +++ case FP_CLS_ZERO: \ +++ R##_s = X##_s; \ +++ R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ +++ break; \ +++ case FP_CLS_NORMAL: \ +++ R##_s = 0; \ +++ if (X##_s) \ +++ { \ +++ R##_c = FP_CLS_NAN; /* sNAN */ \ +++ R##_s = _FP_NANSIGN_##fs; \ +++ _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++ break; \ +++ } \ +++ R##_c = FP_CLS_NORMAL; \ +++ if (X##_e & 1) \ +++ _FP_FRAC_SLL_##wc(X, 1); \ +++ R##_e = X##_e >> 1; \ +++ _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ +++ _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ +++ q = _FP_OVERFLOW_##fs >> 1; \ +++ _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ +++ } \ +++ } while (0) +++ +++/* +++ * Convert from FP to integer. Input is raw. +++ */ +++ +++/* RSIGNED can have following values: +++ * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus +++ * the result is either 0 or (2^rsize)-1 depending on the sign in such +++ * case. +++ * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, +++ * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 +++ * depending on the sign in such case. +++ * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is +++ * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 +++ * depending on the sign in such case. +++ */ +++#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ +++do { \ +++ if (X##_e < _FP_EXPBIAS_##fs) \ +++ { \ +++ r = 0; \ +++ if (X##_e == 0) \ +++ { \ +++ if (!_FP_FRAC_ZEROP_##wc(X)) \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ } \ +++ } \ +++ else \ +++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ +++ } \ +++ else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ +++ || (!rsigned && X##_s)) \ +++ { \ +++ /* Overflow or converting to the most negative integer. */ \ +++ if (rsigned) \ +++ { \ +++ r = 1; \ +++ r <<= rsize - 1; \ +++ r -= 1 - X##_s; \ +++ } else { \ +++ r = 0; \ +++ if (X##_s) \ +++ r = ~r; \ +++ } \ +++ \ +++ if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ +++ { \ +++ /* Possibly converting to most negative integer; check the \ +++ mantissa. */ \ +++ int inexact = 0; \ +++ (void)((_FP_FRACBITS_##fs > rsize) \ +++ ? ({ _FP_FRAC_SRST_##wc(X, inexact, \ +++ _FP_FRACBITS_##fs - rsize, \ +++ _FP_FRACBITS_##fs); 0; }) \ +++ : 0); \ +++ if (!_FP_FRAC_ZEROP_##wc(X)) \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++ else if (inexact) \ +++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ +++ } \ +++ else \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++ } \ +++ else \ +++ { \ +++ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ +++ if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ +++ { \ +++ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ +++ r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ +++ } \ +++ else \ +++ { \ +++ int inexact; \ +++ _FP_FRAC_SRST_##wc(X, inexact, \ +++ (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ +++ - X##_e), \ +++ _FP_FRACBITS_##fs); \ +++ if (inexact) \ +++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ +++ _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ +++ } \ +++ if (rsigned && X##_s) \ +++ r = -r; \ +++ } \ +++} while (0) +++ +++/* Convert integer to fp. Output is raw. RTYPE is unsigned even if +++ input is signed. */ +++#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ +++ do { \ +++ if (r) \ +++ { \ +++ rtype ur_; \ +++ \ +++ if ((X##_s = (r < 0))) \ +++ r = -(rtype)r; \ +++ \ +++ ur_ = (rtype) r; \ +++ (void)((rsize <= _FP_W_TYPE_SIZE) \ +++ ? ({ \ +++ int lz_; \ +++ __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \ +++ X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ +++ }) \ +++ : ((rsize <= 2 * _FP_W_TYPE_SIZE) \ +++ ? ({ \ +++ int lz_; \ +++ __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \ +++ (_FP_W_TYPE)ur_); \ +++ X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ +++ - lz_); \ +++ }) \ +++ : (abort(), 0))); \ +++ \ +++ if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ +++ && X##_e >= _FP_EXPMAX_##fs) \ +++ { \ +++ /* Exponent too big; overflow to infinity. (May also \ +++ happen after rounding below.) */ \ +++ _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ +++ goto pack_semiraw; \ +++ } \ +++ \ +++ if (rsize <= _FP_FRACBITS_##fs \ +++ || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ +++ { \ +++ /* Exactly representable; shift left. */ \ +++ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ +++ _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ +++ + _FP_FRACBITS_##fs - 1 - X##_e)); \ +++ } \ +++ else \ +++ { \ +++ /* More bits in integer than in floating type; need to \ +++ round. */ \ +++ if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ +++ ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ +++ - _FP_WFRACBITS_##fs + 1)) \ +++ | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ +++ - _FP_WFRACBITS_##fs + 1))) \ +++ != 0)); \ +++ _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ +++ if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ +++ _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ +++ + _FP_WFRACBITS_##fs - 1 - X##_e)); \ +++ _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ +++ pack_semiraw: \ +++ _FP_PACK_SEMIRAW(fs, wc, X); \ +++ } \ +++ } \ +++ else \ +++ { \ +++ X##_s = 0; \ +++ X##_e = 0; \ +++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ +++ } \ +++ } while (0) +++ +++ +++/* Extend from a narrower floating-point format to a wider one. Input +++ and output are raw. */ +++#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \ +++do { \ +++ if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ +++ || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ +++ < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ +++ || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ +++ && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ +++ abort(); \ +++ D##_s = S##_s; \ +++ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ +++ if (_FP_EXP_NORMAL(sfs, swc, S)) \ +++ { \ +++ D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ +++ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ +++ } \ +++ else \ +++ { \ +++ if (S##_e == 0) \ +++ { \ +++ if (_FP_FRAC_ZEROP_##swc(S)) \ +++ D##_e = 0; \ +++ else if (_FP_EXPBIAS_##dfs \ +++ < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ +++ - _FP_FRACBITS_##sfs)); \ +++ D##_e = 0; \ +++ } \ +++ else \ +++ { \ +++ int _lz; \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ _FP_FRAC_CLZ_##swc(_lz, S); \ +++ _FP_FRAC_SLL_##dwc(D, \ +++ _lz + _FP_FRACBITS_##dfs \ +++ - _FP_FRACTBITS_##sfs); \ +++ D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ +++ + _FP_FRACXBITS_##sfs - _lz); \ +++ } \ +++ } \ +++ else \ +++ { \ +++ D##_e = _FP_EXPMAX_##dfs; \ +++ if (!_FP_FRAC_ZEROP_##swc(S)) \ +++ { \ +++ if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \ +++ FP_SET_EXCEPTION(FP_EX_INVALID); \ +++ _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ +++ - _FP_FRACBITS_##sfs)); \ +++ } \ +++ } \ +++ } \ +++} while (0) +++ +++/* Truncate from a wider floating-point format to a narrower one. +++ Input and output are semi-raw. */ +++#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ +++do { \ +++ if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ +++ || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ +++ && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ +++ abort(); \ +++ D##_s = S##_s; \ +++ if (_FP_EXP_NORMAL(sfs, swc, S)) \ +++ { \ +++ D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ +++ if (D##_e >= _FP_EXPMAX_##dfs) \ +++ _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \ +++ else \ +++ { \ +++ if (D##_e <= 0) \ +++ { \ +++ if (D##_e < 1 - _FP_FRACBITS_##dfs) \ +++ { \ +++ _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \ +++ _FP_FRAC_LOW_##swc(S) |= 1; \ +++ } \ +++ else \ +++ { \ +++ _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \ +++ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ +++ - _FP_WFRACBITS_##dfs + 1 - D##_e), \ +++ _FP_WFRACBITS_##sfs); \ +++ } \ +++ D##_e = 0; \ +++ } \ +++ else \ +++ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ +++ - _FP_WFRACBITS_##dfs), \ +++ _FP_WFRACBITS_##sfs); \ +++ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ +++ } \ +++ } \ +++ else \ +++ { \ +++ if (S##_e == 0) \ +++ { \ +++ D##_e = 0; \ +++ if (_FP_FRAC_ZEROP_##swc(S)) \ +++ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ +++ else \ +++ { \ +++ FP_SET_EXCEPTION(FP_EX_DENORM); \ +++ if (_FP_EXPBIAS_##sfs \ +++ < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ +++ { \ +++ _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ +++ - _FP_WFRACBITS_##dfs), \ +++ _FP_WFRACBITS_##sfs); \ +++ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ +++ } \ +++ else \ +++ { \ +++ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ +++ _FP_FRAC_LOW_##dwc(D) |= 1; \ +++ } \ +++ } \ +++ } \ +++ else \ +++ { \ +++ D##_e = _FP_EXPMAX_##dfs; \ +++ if (_FP_FRAC_ZEROP_##swc(S)) \ +++ _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ +++ else \ +++ { \ +++ _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \ +++ _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \ +++ - _FP_WFRACBITS_##dfs)); \ +++ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ +++ /* Semi-raw NaN must have all workbits cleared. */ \ +++ _FP_FRAC_LOW_##dwc(D) \ +++ &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ +++ _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \ +++ } \ +++ } \ +++ } \ +++} while (0) +++ +++/* +++ * Helper primitives. +++ */ +++ +++/* Count leading zeros in a word. */ +++ +++#ifndef __FP_CLZ +++/* GCC 3.4 and later provide the builtins for us. */ +++#define __FP_CLZ(r, x) \ +++ do { \ +++ if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ +++ r = __builtin_clz (x); \ +++ else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ +++ r = __builtin_clzl (x); \ +++ else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ +++ r = __builtin_clzll (x); \ +++ else \ +++ abort (); \ +++ } while (0) +++#endif /* ndef __FP_CLZ */ +++ +++#define _FP_DIV_HELP_imm(q, r, n, d) \ +++ do { \ +++ q = n / d, r = n % d; \ +++ } while (0) +++ +++ +++/* A restoring bit-by-bit division primitive. */ +++ +++#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ +++ do { \ +++ int count = _FP_WFRACBITS_##fs; \ +++ _FP_FRAC_DECL_##wc (u); \ +++ _FP_FRAC_DECL_##wc (v); \ +++ _FP_FRAC_COPY_##wc (u, X); \ +++ _FP_FRAC_COPY_##wc (v, Y); \ +++ _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ +++ /* Normalize U and V. */ \ +++ _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ +++ _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ +++ /* First round. Since the operands are normalized, either the \ +++ first or second bit will be set in the fraction. Produce a \ +++ normalized result by checking which and adjusting the loop \ +++ count and exponent accordingly. */ \ +++ if (_FP_FRAC_GE_1 (u, v)) \ +++ { \ +++ _FP_FRAC_SUB_##wc (u, u, v); \ +++ _FP_FRAC_LOW_##wc (R) |= 1; \ +++ count--; \ +++ } \ +++ else \ +++ R##_e--; \ +++ /* Subsequent rounds. */ \ +++ do { \ +++ int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ +++ _FP_FRAC_SLL_##wc (u, 1); \ +++ _FP_FRAC_SLL_##wc (R, 1); \ +++ if (msb || _FP_FRAC_GE_1 (u, v)) \ +++ { \ +++ _FP_FRAC_SUB_##wc (u, u, v); \ +++ _FP_FRAC_LOW_##wc (R) |= 1; \ +++ } \ +++ } while (--count > 0); \ +++ /* If there's anything left in U, the result is inexact. */ \ +++ _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ +++ } while (0) +++ +++#define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) +++#define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) +++#define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y) ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_add.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_add.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_add.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_add.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,39 @@ +++/* Software floating-point emulation. +++ Return a + b +++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_add(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); +++ long double c; +++ +++ FP_INIT_ROUNDMODE; +++ FP_UNPACK_SEMIRAW_Q(A, a); +++ FP_UNPACK_SEMIRAW_Q(B, b); +++ FP_ADD_Q(C, A, B); +++ FP_PACK_SEMIRAW_Q(c, C); +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmp.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,41 @@ +++/* Software floating-point emulation. +++ Compare a and b, return float condition code. +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++int _Q_cmp(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); +++ int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_UNPACK_RAW_Q(B, b); +++ FP_CMP_Q(r, B, A, 3); +++ if (r == -1) r = 2; +++ if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) +++ FP_SET_EXCEPTION(FP_EX_INVALID); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_cmpe.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,42 @@ +++/* Software floating-point emulation. +++ Compare a and b, return float condition code. +++ Signal exception (unless masked) if unordered. +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++int _Q_cmpe(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); +++ int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_UNPACK_RAW_Q(B, b); +++ FP_CMP_Q(r, B, A, 3); +++ if (r == -1) r = 2; +++ if (r == 3) +++ FP_SET_EXCEPTION(FP_EX_INVALID); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_div.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_div.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_div.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_div.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,39 @@ +++/* Software floating-point emulation. +++ Return a / b +++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_div(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); +++ long double c; +++ +++ FP_INIT_ROUNDMODE; +++ FP_UNPACK_Q(A, a); +++ FP_UNPACK_Q(B, b); +++ FP_DIV_Q(C, A, B); +++ FP_PACK_Q(c, C); +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_dtoq.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,44 @@ +++/* Software floating-point emulation. +++ Return (long double)(a) +++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "double.h" +++#include "quad.h" +++ +++long double _Q_dtoq(const double a) +++{ +++ FP_DECL_EX; +++ FP_DECL_D(A); +++ FP_DECL_Q(C); +++ long double c; +++ +++ FP_INIT_ROUNDMODE; +++ FP_UNPACK_RAW_D(A, a); +++#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q +++ FP_EXTEND(Q,D,4,2,C,A); +++#else +++ FP_EXTEND(Q,D,2,1,C,A); +++#endif +++ FP_PACK_RAW_Q(c, C); +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_feq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_feq.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_feq.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_feq.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,40 @@ +++/* Software floating-point emulation. +++ Return 1 if a == b +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++int _Q_feq(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); +++ int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_UNPACK_RAW_Q(B, b); +++ FP_CMP_EQ_Q(r, A, B); +++ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) +++ FP_SET_EXCEPTION(FP_EX_INVALID); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return !r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fge.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fge.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fge.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fge.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,40 @@ +++/* Software floating-point emulation. +++ Return 1 if a >= b +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++int _Q_fge(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); +++ int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_UNPACK_RAW_Q(B, b); +++ FP_CMP_Q(r, B, A, 3); +++ if (r == 3) +++ FP_SET_EXCEPTION(FP_EX_INVALID); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return (r <= 0); +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fgt.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,40 @@ +++/* Software floating-point emulation. +++ Return 1 if a > b +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++int _Q_fgt(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); +++ int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_UNPACK_RAW_Q(B, b); +++ FP_CMP_Q(r, B, A, 3); +++ if (r == 3) +++ FP_SET_EXCEPTION(FP_EX_INVALID); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return (r == -1); +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fle.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fle.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fle.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fle.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,40 @@ +++/* Software floating-point emulation. +++ Return 1 if a <= b +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++int _Q_fle(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); +++ int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_UNPACK_RAW_Q(B, b); +++ FP_CMP_Q(r, B, A, -2); +++ if (r == -2) +++ FP_SET_EXCEPTION(FP_EX_INVALID); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return (r >= 0); +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_flt.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_flt.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_flt.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_flt.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,40 @@ +++/* Software floating-point emulation. +++ Return 1 if a < b +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++int _Q_flt(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); +++ int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_UNPACK_RAW_Q(B, b); +++ FP_CMP_Q(r, B, A, 3); +++ if (r == 3) +++ FP_SET_EXCEPTION(FP_EX_INVALID); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return (r == 1); +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fne.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fne.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_fne.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_fne.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,40 @@ +++/* Software floating-point emulation. +++ Return 1 if a != b +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++int _Q_fne(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); +++ int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_UNPACK_RAW_Q(B, b); +++ FP_CMP_EQ_Q(r, A, B); +++ if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) +++ FP_SET_EXCEPTION(FP_EX_INVALID); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_itoq.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,38 @@ +++/* Software floating-point emulation. +++ Return (long double)(a) +++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_itoq(const int a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(C); +++ int b = a; +++ long double c; +++ +++ FP_FROM_INT_Q(C, b, 32, unsigned int); +++ FP_PACK_RAW_Q(c, C); +++ FP_CLEAR_EXCEPTIONS; +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_lltoq.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,38 @@ +++/* Software floating-point emulation. +++ Return (long double)a +++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_lltoq(const long long a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(C); +++ long double c; +++ long long b = a; +++ +++ FP_FROM_INT_Q(C, b, 64, unsigned long long); +++ FP_PACK_RAW_Q(c, C); +++ FP_CLEAR_EXCEPTIONS; +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_mul.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_mul.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_mul.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_mul.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,39 @@ +++/* Software floating-point emulation. +++ Return a * b +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_mul(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); +++ long double c; +++ +++ FP_INIT_ROUNDMODE; +++ FP_UNPACK_Q(A, a); +++ FP_UNPACK_Q(B, b); +++ FP_MUL_Q(C, A, B); +++ FP_PACK_Q(c, C); +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_neg.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_neg.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_neg.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_neg.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,47 @@ +++/* Software floating-point emulation. +++ Return !a +++ Copyright (C) 1997,1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_neg(const long double a) +++{ +++ FP_DECL_EX; +++ long double c = a; +++ +++#if (__BYTE_ORDER == __BIG_ENDIAN) +++ ((UWtype *)&c)[0] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); +++#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 64) +++ ((UWtype *)&c)[1] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); +++#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 32) +++ ((UWtype *)&c)[3] ^= (((UWtype)1) << (W_TYPE_SIZE - 1)); +++#else +++ FP_DECL_Q(A); FP_DECL_Q(C); +++ +++ FP_UNPACK_Q(A, a); +++ FP_NEG_Q(C, A); +++ FP_PACK_Q(c, C); +++#endif +++ FP_CLEAR_EXCEPTIONS; +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtod.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,45 @@ +++/* Software floating-point emulation. +++ Return (double)a +++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "double.h" +++#include "quad.h" +++ +++double _Q_qtod(const long double a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); +++ FP_DECL_D(R); +++ double r; +++ +++ FP_INIT_ROUNDMODE; +++ FP_UNPACK_SEMIRAW_Q(A, a); +++#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q +++ FP_TRUNC(D,Q,2,4,R,A); +++#else +++ FP_TRUNC(D,Q,1,2,R,A); +++#endif +++ FP_PACK_SEMIRAW_D(r, R); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoi.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,38 @@ +++/* Software floating-point emulation. +++ Return (int)a +++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#define FP_ROUNDMODE FP_RND_ZERO +++#include "soft-fp.h" +++#include "quad.h" +++ +++int _Q_qtoi(const long double a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); +++ unsigned int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_TO_INT_Q(r, A, 32, 1); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoll.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,38 @@ +++/* Software floating-point emulation. +++ Return (long long)a +++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#define FP_ROUNDMODE FP_RND_ZERO +++#include "soft-fp.h" +++#include "quad.h" +++ +++long long _Q_qtoll(const long double a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); +++ unsigned long long r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_TO_INT_Q(r, A, 64, 1); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtos.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,45 @@ +++/* Software floating-point emulation. +++ Return (float)a +++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "single.h" +++#include "quad.h" +++ +++float _Q_qtos(const long double a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); +++ FP_DECL_S(R); +++ float r; +++ +++ FP_INIT_ROUNDMODE; +++ FP_UNPACK_SEMIRAW_Q(A, a); +++#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q +++ FP_TRUNC(S,Q,1,4,R,A); +++#else +++ FP_TRUNC(S,Q,1,2,R,A); +++#endif +++ FP_PACK_SEMIRAW_S(r, R); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtou.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,38 @@ +++/* Software floating-point emulation. +++ Return (unsigned int)a +++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#define FP_ROUNDMODE FP_RND_ZERO +++#include "soft-fp.h" +++#include "quad.h" +++ +++unsigned int _Q_qtou(const long double a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); +++ unsigned int r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_TO_INT_Q(r, A, 32, -1); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_qtoull.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,38 @@ +++/* Software floating-point emulation. +++ Return (unsigned long long)a +++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#define FP_ROUNDMODE FP_RND_ZERO +++#include "soft-fp.h" +++#include "quad.h" +++ +++unsigned long long _Q_qtoull(const long double a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); +++ unsigned long long r; +++ +++ FP_UNPACK_RAW_Q(A, a); +++ FP_TO_INT_Q(r, A, 64, -1); +++ FP_HANDLE_EXCEPTIONS; +++ +++ return r; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sqrt.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,39 @@ +++/* Software floating-point emulation. +++ Return sqrtl(a) +++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_sqrt(const long double a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(C); +++ long double c; +++ +++ FP_INIT_ROUNDMODE; +++ FP_UNPACK_Q(A, a); +++ FP_SQRT_Q(C, A); +++ FP_PACK_Q(c, C); +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} +++strong_alias (_Q_sqrt, __ieee754_sqrtl); ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_stoq.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,43 @@ +++/* Software floating-point emulation. +++ c = (long double)(a) +++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "single.h" +++#include "quad.h" +++ +++long double _Q_stoq(const float a) +++{ +++ FP_DECL_EX; +++ FP_DECL_S(A); +++ FP_DECL_Q(C); +++ long double c; +++ +++ FP_UNPACK_RAW_S(A, a); +++#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q +++ FP_EXTEND(Q,S,4,1,C,A); +++#else +++ FP_EXTEND(Q,S,2,1,C,A); +++#endif +++ FP_PACK_RAW_Q(c, C); +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sub.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sub.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_sub.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_sub.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,39 @@ +++/* Software floating-point emulation. +++ c = a - b +++ Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_sub(const long double a, const long double b) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); +++ long double c; +++ +++ FP_INIT_ROUNDMODE; +++ FP_UNPACK_SEMIRAW_Q(A, a); +++ FP_UNPACK_SEMIRAW_Q(B, b); +++ FP_SUB_Q(C, A, B); +++ FP_PACK_SEMIRAW_Q(c, C); +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_ulltoq.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,38 @@ +++/* Software floating-point emulation. +++ Return (long double)(a) +++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_ulltoq(const unsigned long long a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(C); +++ long double c; +++ unsigned long long b = a; +++ +++ FP_FROM_INT_Q(C, b, 64, unsigned long long); +++ FP_PACK_RAW_Q(c, C); +++ FP_CLEAR_EXCEPTIONS; +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_util.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_util.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_util.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_util.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,57 @@ +++/* Software floating-point emulation. +++ Helper routine for _Q_* routines. +++ Simulate exceptions using double arithmetics. +++ Copyright (C) 1999 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++ +++unsigned long long ___Q_numbers [] = { +++0x0000000000000000ULL, /* Zero */ +++0x0010100000000000ULL, /* Very tiny number */ +++0x0010000000000000ULL, /* Minimum normalized number */ +++0x7fef000000000000ULL, /* A huge double number */ +++}; +++ +++double ___Q_simulate_exceptions(int exceptions) +++{ +++ double d, *p = (double *)___Q_numbers; +++ if (exceptions & FP_EX_INVALID) +++ d = p[0]/p[0]; +++ if (exceptions & FP_EX_OVERFLOW) +++ { +++ d = p[3] + p[3]; +++ exceptions &= ~FP_EX_INEXACT; +++ } +++ if (exceptions & FP_EX_UNDERFLOW) +++ { +++ if (exceptions & FP_EX_INEXACT) +++ { +++ d = p[2] * p[2]; +++ exceptions &= ~FP_EX_INEXACT; +++ } +++ else +++ d = p[1] - p[2]; +++ } +++ if (exceptions & FP_EX_DIVZERO) +++ d = 1.0/p[0]; +++ if (exceptions & FP_EX_INEXACT) +++ d = p[3] - p[2]; +++ return d; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/q_utoq.c 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,38 @@ +++/* Software floating-point emulation. +++ c = (long double)(a) +++ Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com) and +++ Jakub Jelinek (jj@ultra.linux.cz). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include "soft-fp.h" +++#include "quad.h" +++ +++long double _Q_utoq(const unsigned int a) +++{ +++ FP_DECL_EX; +++ FP_DECL_Q(C); +++ long double c; +++ unsigned int b = a; +++ +++ FP_FROM_INT_Q(C, b, 32, unsigned int); +++ FP_PACK_RAW_Q(c, C); +++ FP_CLEAR_EXCEPTIONS; +++ FP_HANDLE_EXCEPTIONS; +++ return c; +++} ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/quad.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/quad.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/quad.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/quad.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,271 @@ +++/* Software floating-point emulation. +++ Definitions for IEEE Quad Precision. +++ Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz), +++ David S. Miller (davem@redhat.com) and +++ Peter Maydell (pmaydell@chiark.greenend.org.uk). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++#if _FP_W_TYPE_SIZE < 32 +++#error "Here's a nickel, kid. Go buy yourself a real computer." +++#endif +++ +++#if _FP_W_TYPE_SIZE < 64 +++#define _FP_FRACTBITS_Q (4*_FP_W_TYPE_SIZE) +++#else +++#define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE) +++#endif +++ +++#define _FP_FRACBITS_Q 113 +++#define _FP_FRACXBITS_Q (_FP_FRACTBITS_Q - _FP_FRACBITS_Q) +++#define _FP_WFRACBITS_Q (_FP_WORKBITS + _FP_FRACBITS_Q) +++#define _FP_WFRACXBITS_Q (_FP_FRACTBITS_Q - _FP_WFRACBITS_Q) +++#define _FP_EXPBITS_Q 15 +++#define _FP_EXPBIAS_Q 16383 +++#define _FP_EXPMAX_Q 32767 +++ +++#define _FP_QNANBIT_Q \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE) +++#define _FP_QNANBIT_SH_Q \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) +++#define _FP_IMPLBIT_Q \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE) +++#define _FP_IMPLBIT_SH_Q \ +++ ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) +++#define _FP_OVERFLOW_Q \ +++ ((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE)) +++ +++typedef float TFtype __attribute__((mode(TF))); +++ +++#if _FP_W_TYPE_SIZE < 64 +++ +++union _FP_UNION_Q +++{ +++ TFtype flt; +++ struct +++ { +++#if __BYTE_ORDER == __BIG_ENDIAN +++ unsigned sign : 1; +++ unsigned exp : _FP_EXPBITS_Q; +++ unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); +++ unsigned long frac2 : _FP_W_TYPE_SIZE; +++ unsigned long frac1 : _FP_W_TYPE_SIZE; +++ unsigned long frac0 : _FP_W_TYPE_SIZE; +++#else +++ unsigned long frac0 : _FP_W_TYPE_SIZE; +++ unsigned long frac1 : _FP_W_TYPE_SIZE; +++ unsigned long frac2 : _FP_W_TYPE_SIZE; +++ unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); +++ unsigned exp : _FP_EXPBITS_Q; +++ unsigned sign : 1; +++#endif /* not bigendian */ +++ } bits __attribute__((packed)); +++}; +++ +++ +++#define FP_DECL_Q(X) _FP_DECL(4,X) +++#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val) +++#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_4_P(Q,X,val) +++#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_4(Q,val,X) +++#define FP_PACK_RAW_QP(val,X) \ +++ do { \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_4_P(Q,val,X); \ +++ } while (0) +++ +++#define FP_UNPACK_Q(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_4(Q,X,val); \ +++ _FP_UNPACK_CANONICAL(Q,4,X); \ +++ } while (0) +++ +++#define FP_UNPACK_QP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_4_P(Q,X,val); \ +++ _FP_UNPACK_CANONICAL(Q,4,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_Q(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_4(Q,X,val); \ +++ _FP_UNPACK_SEMIRAW(Q,4,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_QP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_4_P(Q,X,val); \ +++ _FP_UNPACK_SEMIRAW(Q,4,X); \ +++ } while (0) +++ +++#define FP_PACK_Q(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(Q,4,X); \ +++ _FP_PACK_RAW_4(Q,val,X); \ +++ } while (0) +++ +++#define FP_PACK_QP(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(Q,4,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_4_P(Q,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_Q(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(Q,4,X); \ +++ _FP_PACK_RAW_4(Q,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_QP(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(Q,4,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_4_P(Q,val,X); \ +++ } while (0) +++ +++#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,4,X) +++#define FP_NEG_Q(R,X) _FP_NEG(Q,4,R,X) +++#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,4,R,X,Y) +++#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,4,R,X,Y) +++#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,4,R,X,Y) +++#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,4,R,X,Y) +++#define FP_SQRT_Q(R,X) _FP_SQRT(Q,4,R,X) +++#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_4(R,S,T,X,Q) +++ +++#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,4,r,X,Y,un) +++#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,4,r,X,Y) +++#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,4,r,X,Y) +++ +++#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,4,r,X,rsz,rsg) +++#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,4,X,r,rs,rt) +++ +++#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4(X) +++#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4(X) +++ +++#else /* not _FP_W_TYPE_SIZE < 64 */ +++union _FP_UNION_Q +++{ +++ TFtype flt /* __attribute__((mode(TF))) */ ; +++ struct { +++ _FP_W_TYPE a, b; +++ } longs; +++ struct { +++#if __BYTE_ORDER == __BIG_ENDIAN +++ unsigned sign : 1; +++ unsigned exp : _FP_EXPBITS_Q; +++ _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; +++ _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; +++#else +++ _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; +++ _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; +++ unsigned exp : _FP_EXPBITS_Q; +++ unsigned sign : 1; +++#endif +++ } bits; +++}; +++ +++#define FP_DECL_Q(X) _FP_DECL(2,X) +++#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val) +++#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_2_P(Q,X,val) +++#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_2(Q,val,X) +++#define FP_PACK_RAW_QP(val,X) \ +++ do { \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_2_P(Q,val,X); \ +++ } while (0) +++ +++#define FP_UNPACK_Q(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2(Q,X,val); \ +++ _FP_UNPACK_CANONICAL(Q,2,X); \ +++ } while (0) +++ +++#define FP_UNPACK_QP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2_P(Q,X,val); \ +++ _FP_UNPACK_CANONICAL(Q,2,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_Q(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2(Q,X,val); \ +++ _FP_UNPACK_SEMIRAW(Q,2,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_QP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_2_P(Q,X,val); \ +++ _FP_UNPACK_SEMIRAW(Q,2,X); \ +++ } while (0) +++ +++#define FP_PACK_Q(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(Q,2,X); \ +++ _FP_PACK_RAW_2(Q,val,X); \ +++ } while (0) +++ +++#define FP_PACK_QP(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(Q,2,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_2_P(Q,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_Q(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(Q,2,X); \ +++ _FP_PACK_RAW_2(Q,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_QP(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(Q,2,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_2_P(Q,val,X); \ +++ } while (0) +++ +++#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,2,X) +++#define FP_NEG_Q(R,X) _FP_NEG(Q,2,R,X) +++#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,2,R,X,Y) +++#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,2,R,X,Y) +++#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,2,R,X,Y) +++#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,2,R,X,Y) +++#define FP_SQRT_Q(R,X) _FP_SQRT(Q,2,R,X) +++#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) +++ +++#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un) +++#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y) +++#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,2,r,X,Y) +++ +++#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg) +++#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt) +++ +++#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2(X) +++#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2(X) +++ +++#endif /* not _FP_W_TYPE_SIZE < 64 */ ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/sfp-machine.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,213 @@ +++/* Machine-dependent software floating-point definitions. +++ Sparc userland (_Q_*) version. +++ Copyright (C) 1997,1998,1999, 2002, 2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz) and +++ David S. Miller (davem@redhat.com). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +++ 02111-1307 USA. */ +++ +++#include +++#include +++ +++#define _FP_W_TYPE_SIZE 32 +++#define _FP_W_TYPE unsigned long +++#define _FP_WS_TYPE signed long +++#define _FP_I_TYPE long +++ +++#define _FP_MUL_MEAT_S(R,X,Y) \ +++ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) +++#define _FP_MUL_MEAT_D(R,X,Y) \ +++ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +++#define _FP_MUL_MEAT_Q(R,X,Y) \ +++ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) +++ +++#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) +++#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) +++#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) +++ +++#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) +++#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1 +++#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1 +++#define _FP_NANSIGN_S 0 +++#define _FP_NANSIGN_D 0 +++#define _FP_NANSIGN_Q 0 +++ +++#define _FP_KEEPNANFRACP 1 +++ +++/* If one NaN is signaling and the other is not, +++ * we choose that one, otherwise we choose X. +++ */ +++/* For _Qp_* and _Q_*, this should prefer X, for +++ * CPU instruction emulation this should prefer Y. +++ * (see SPAMv9 B.2.2 section). +++ */ +++#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ +++ do { \ +++ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ +++ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \ +++ { \ +++ R##_s = Y##_s; \ +++ _FP_FRAC_COPY_##wc(R,Y); \ +++ } \ +++ else \ +++ { \ +++ R##_s = X##_s; \ +++ _FP_FRAC_COPY_##wc(R,X); \ +++ } \ +++ R##_c = FP_CLS_NAN; \ +++ } while (0) +++ +++/* Some assembly to speed things up. */ +++#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ +++ __asm__ ("addcc %r7,%8,%2\n\ +++ addxcc %r5,%6,%1\n\ +++ addx %r3,%4,%0" \ +++ : "=r" ((USItype)(r2)), \ +++ "=&r" ((USItype)(r1)), \ +++ "=&r" ((USItype)(r0)) \ +++ : "%rJ" ((USItype)(x2)), \ +++ "rI" ((USItype)(y2)), \ +++ "%rJ" ((USItype)(x1)), \ +++ "rI" ((USItype)(y1)), \ +++ "%rJ" ((USItype)(x0)), \ +++ "rI" ((USItype)(y0)) \ +++ : "cc") +++ +++#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ +++ __asm__ ("subcc %r7,%8,%2\n\ +++ subxcc %r5,%6,%1\n\ +++ subx %r3,%4,%0" \ +++ : "=r" ((USItype)(r2)), \ +++ "=&r" ((USItype)(r1)), \ +++ "=&r" ((USItype)(r0)) \ +++ : "%rJ" ((USItype)(x2)), \ +++ "rI" ((USItype)(y2)), \ +++ "%rJ" ((USItype)(x1)), \ +++ "rI" ((USItype)(y1)), \ +++ "%rJ" ((USItype)(x0)), \ +++ "rI" ((USItype)(y0)) \ +++ : "cc") +++ +++#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ +++ do { \ +++ /* We need to fool gcc, as we need to pass more than 10 \ +++ input/outputs. */ \ +++ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \ +++ __asm__ __volatile__ ("\ +++ addcc %r8,%9,%1\n\ +++ addxcc %r6,%7,%0\n\ +++ addxcc %r4,%5,%%g2\n\ +++ addx %r2,%3,%%g1" \ +++ : "=&r" ((USItype)(r1)), \ +++ "=&r" ((USItype)(r0)) \ +++ : "%rJ" ((USItype)(x3)), \ +++ "rI" ((USItype)(y3)), \ +++ "%rJ" ((USItype)(x2)), \ +++ "rI" ((USItype)(y2)), \ +++ "%rJ" ((USItype)(x1)), \ +++ "rI" ((USItype)(y1)), \ +++ "%rJ" ((USItype)(x0)), \ +++ "rI" ((USItype)(y0)) \ +++ : "cc", "g1", "g2"); \ +++ __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \ +++ r3 = _t1; r2 = _t2; \ +++ } while (0) +++ +++#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ +++ do { \ +++ /* We need to fool gcc, as we need to pass more than 10 \ +++ input/outputs. */ \ +++ register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \ +++ __asm__ __volatile__ ("\ +++ subcc %r8,%9,%1\n\ +++ subxcc %r6,%7,%0\n\ +++ subxcc %r4,%5,%%g2\n\ +++ subx %r2,%3,%%g1" \ +++ : "=&r" ((USItype)(r1)), \ +++ "=&r" ((USItype)(r0)) \ +++ : "%rJ" ((USItype)(x3)), \ +++ "rI" ((USItype)(y3)), \ +++ "%rJ" ((USItype)(x2)), \ +++ "rI" ((USItype)(y2)), \ +++ "%rJ" ((USItype)(x1)), \ +++ "rI" ((USItype)(y1)), \ +++ "%rJ" ((USItype)(x0)), \ +++ "rI" ((USItype)(y0)) \ +++ : "cc", "g1", "g2"); \ +++ __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \ +++ r3 = _t1; r2 = _t2; \ +++ } while (0) +++ +++#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0) +++ +++#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0) +++ +++#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ +++ __asm__ ("addcc %3,%4,%3\n\ +++ addxcc %2,%%g0,%2\n\ +++ addxcc %1,%%g0,%1\n\ +++ addx %0,%%g0,%0" \ +++ : "=&r" ((USItype)(x3)), \ +++ "=&r" ((USItype)(x2)), \ +++ "=&r" ((USItype)(x1)), \ +++ "=&r" ((USItype)(x0)) \ +++ : "rI" ((USItype)(i)), \ +++ "0" ((USItype)(x3)), \ +++ "1" ((USItype)(x2)), \ +++ "2" ((USItype)(x1)), \ +++ "3" ((USItype)(x0)) \ +++ : "cc") +++ +++/* Obtain the current rounding mode. */ +++#ifndef FP_ROUNDMODE +++#define FP_ROUNDMODE ((_fcw >> 30) & 0x3) +++#endif +++ +++/* Exception flags. */ +++#define FP_EX_INVALID (1 << 4) +++#define FP_EX_OVERFLOW (1 << 3) +++#define FP_EX_UNDERFLOW (1 << 2) +++#define FP_EX_DIVZERO (1 << 1) +++#define FP_EX_INEXACT (1 << 0) +++ +++#define _FP_DECL_EX fpu_control_t _fcw +++ +++#define FP_INIT_ROUNDMODE \ +++do { \ +++ _FPU_GETCW(_fcw); \ +++} while (0) +++ +++/* Simulate exceptions using double arithmetics. */ +++extern double ___Q_simulate_exceptions(int exc); +++ +++#define FP_HANDLE_EXCEPTIONS \ +++do { \ +++ if (!_fex) \ +++ { \ +++ /* This is the common case, so we do it inline. \ +++ * We need to clear cexc bits if any. \ +++ */ \ +++ extern unsigned long long ___Q_numbers[]; \ +++ __asm__ __volatile__("\ +++ ldd [%0], %%f30\n\ +++ faddd %%f30, %%f30, %%f30\ +++ " : : "r" (___Q_numbers) : "f30"); \ +++ } \ +++ else \ +++ ___Q_simulate_exceptions (_fex); \ +++} while (0) ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/single.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/single.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/single.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/single.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,151 @@ +++/* Software floating-point emulation. +++ Definitions for IEEE Single Precision. +++ Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz), +++ David S. Miller (davem@redhat.com) and +++ Peter Maydell (pmaydell@chiark.greenend.org.uk). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++#if _FP_W_TYPE_SIZE < 32 +++#error "Here's a nickel kid. Go buy yourself a real computer." +++#endif +++ +++#define _FP_FRACTBITS_S _FP_W_TYPE_SIZE +++ +++#define _FP_FRACBITS_S 24 +++#define _FP_FRACXBITS_S (_FP_FRACTBITS_S - _FP_FRACBITS_S) +++#define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S) +++#define _FP_WFRACXBITS_S (_FP_FRACTBITS_S - _FP_WFRACBITS_S) +++#define _FP_EXPBITS_S 8 +++#define _FP_EXPBIAS_S 127 +++#define _FP_EXPMAX_S 255 +++#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2)) +++#define _FP_QNANBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2+_FP_WORKBITS)) +++#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1)) +++#define _FP_IMPLBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1+_FP_WORKBITS)) +++#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S)) +++ +++/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be +++ chosen by the target machine. */ +++ +++typedef float SFtype __attribute__((mode(SF))); +++ +++union _FP_UNION_S +++{ +++ SFtype flt; +++ struct { +++#if __BYTE_ORDER == __BIG_ENDIAN +++ unsigned sign : 1; +++ unsigned exp : _FP_EXPBITS_S; +++ unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); +++#else +++ unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); +++ unsigned exp : _FP_EXPBITS_S; +++ unsigned sign : 1; +++#endif +++ } bits __attribute__((packed)); +++}; +++ +++#define FP_DECL_S(X) _FP_DECL(1,X) +++#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val) +++#define FP_UNPACK_RAW_SP(X,val) _FP_UNPACK_RAW_1_P(S,X,val) +++#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X) +++#define FP_PACK_RAW_SP(val,X) \ +++ do { \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_1_P(S,val,X); \ +++ } while (0) +++ +++#define FP_UNPACK_S(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_1(S,X,val); \ +++ _FP_UNPACK_CANONICAL(S,1,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_1_P(S,X,val); \ +++ _FP_UNPACK_CANONICAL(S,1,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_S(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_1(S,X,val); \ +++ _FP_UNPACK_SEMIRAW(S,1,X); \ +++ } while (0) +++ +++#define FP_UNPACK_SEMIRAW_SP(X,val) \ +++ do { \ +++ _FP_UNPACK_RAW_1_P(S,X,val); \ +++ _FP_UNPACK_SEMIRAW(S,1,X); \ +++ } while (0) +++ +++#define FP_PACK_S(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(S,1,X); \ +++ _FP_PACK_RAW_1(S,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SP(val,X) \ +++ do { \ +++ _FP_PACK_CANONICAL(S,1,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_1_P(S,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_S(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(S,1,X); \ +++ _FP_PACK_RAW_1(S,val,X); \ +++ } while (0) +++ +++#define FP_PACK_SEMIRAW_SP(val,X) \ +++ do { \ +++ _FP_PACK_SEMIRAW(S,1,X); \ +++ if (!FP_INHIBIT_RESULTS) \ +++ _FP_PACK_RAW_1_P(S,val,X); \ +++ } while (0) +++ +++#define FP_ISSIGNAN_S(X) _FP_ISSIGNAN(S,1,X) +++#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X) +++#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y) +++#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y) +++#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y) +++#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y) +++#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X) +++#define _FP_SQRT_MEAT_S(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) +++ +++#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un) +++#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y) +++#define FP_CMP_UNORD_S(r,X,Y) _FP_CMP_UNORD(S,1,r,X,Y) +++ +++#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg) +++#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt) +++ +++#define _FP_FRAC_HIGH_S(X) _FP_FRAC_HIGH_1(X) +++#define _FP_FRAC_HIGH_RAW_S(X) _FP_FRAC_HIGH_1(X) ++diff -Naur uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h ++--- uClibc-0.9.31.ori/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h 1970-01-01 01:00:00.000000000 +0100 +++++ uClibc-0.9.31/libc/sysdeps/linux/sparc/soft-fp/soft-fp.h 2010-10-14 14:05:37.000000000 +0200 ++@@ -0,0 +1,205 @@ +++/* Software floating-point emulation. +++ Copyright (C) 1997,1998,1999,2000,2002,2003,2005,2006,2007 +++ Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ Contributed by Richard Henderson (rth@cygnus.com), +++ Jakub Jelinek (jj@ultra.linux.cz), +++ David S. Miller (davem@redhat.com) and +++ Peter Maydell (pmaydell@chiark.greenend.org.uk). +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ In addition to the permissions in the GNU Lesser General Public +++ License, the Free Software Foundation gives you unlimited +++ permission to link the compiled version of this file into +++ combinations with other programs, and to distribute those +++ combinations without any restriction coming from the use of this +++ file. (The Lesser General Public License restrictions do apply in +++ other respects; for example, they cover modification of the file, +++ and distribution when not linked into a combine executable.) +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, write to the Free +++ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, +++ MA 02110-1301, USA. */ +++ +++#ifndef SOFT_FP_H +++#define SOFT_FP_H +++ +++#include "sfp-machine.h" +++ +++/* Allow sfp-machine to have its own byte order definitions. */ +++#ifndef __BYTE_ORDER +++#ifdef _LIBC +++#include +++#else +++#error "endianness not defined by sfp-machine.h" +++#endif +++#endif +++ +++#define _FP_WORKBITS 3 +++#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) +++#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) +++#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) +++#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) +++ +++#ifndef FP_RND_NEAREST +++# define FP_RND_NEAREST 0 +++# define FP_RND_ZERO 1 +++# define FP_RND_PINF 2 +++# define FP_RND_MINF 3 +++#endif +++#ifndef FP_ROUNDMODE +++# define FP_ROUNDMODE FP_RND_NEAREST +++#endif +++ +++/* By default don't care about exceptions. */ +++#ifndef FP_EX_INVALID +++#define FP_EX_INVALID 0 +++#endif +++#ifndef FP_EX_OVERFLOW +++#define FP_EX_OVERFLOW 0 +++#endif +++#ifndef FP_EX_UNDERFLOW +++#define FP_EX_UNDERFLOW 0 +++#endif +++#ifndef FP_EX_DIVZERO +++#define FP_EX_DIVZERO 0 +++#endif +++#ifndef FP_EX_INEXACT +++#define FP_EX_INEXACT 0 +++#endif +++#ifndef FP_EX_DENORM +++#define FP_EX_DENORM 0 +++#endif +++ +++#ifdef _FP_DECL_EX +++#define FP_DECL_EX \ +++ int _fex = 0; \ +++ _FP_DECL_EX +++#else +++#define FP_DECL_EX int _fex = 0 +++#endif +++ +++#ifndef FP_INIT_ROUNDMODE +++#define FP_INIT_ROUNDMODE do {} while (0) +++#endif +++ +++#ifndef FP_HANDLE_EXCEPTIONS +++#define FP_HANDLE_EXCEPTIONS do {} while (0) +++#endif +++ +++#ifndef FP_INHIBIT_RESULTS +++/* By default we write the results always. +++ * sfp-machine may override this and e.g. +++ * check if some exceptions are unmasked +++ * and inhibit it in such a case. +++ */ +++#define FP_INHIBIT_RESULTS 0 +++#endif +++ +++#define FP_SET_EXCEPTION(ex) \ +++ _fex |= (ex) +++ +++#define FP_UNSET_EXCEPTION(ex) \ +++ _fex &= ~(ex) +++ +++#define FP_CLEAR_EXCEPTIONS \ +++ _fex = 0 +++ +++#define _FP_ROUND_NEAREST(wc, X) \ +++do { \ +++ if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ +++ _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ +++} while (0) +++ +++#define _FP_ROUND_ZERO(wc, X) (void)0 +++ +++#define _FP_ROUND_PINF(wc, X) \ +++do { \ +++ if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ +++ _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ +++} while (0) +++ +++#define _FP_ROUND_MINF(wc, X) \ +++do { \ +++ if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ +++ _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ +++} while (0) +++ +++#define _FP_ROUND(wc, X) \ +++do { \ +++ if (_FP_FRAC_LOW_##wc(X) & 7) \ +++ FP_SET_EXCEPTION(FP_EX_INEXACT); \ +++ switch (FP_ROUNDMODE) \ +++ { \ +++ case FP_RND_NEAREST: \ +++ _FP_ROUND_NEAREST(wc,X); \ +++ break; \ +++ case FP_RND_ZERO: \ +++ _FP_ROUND_ZERO(wc,X); \ +++ break; \ +++ case FP_RND_PINF: \ +++ _FP_ROUND_PINF(wc,X); \ +++ break; \ +++ case FP_RND_MINF: \ +++ _FP_ROUND_MINF(wc,X); \ +++ break; \ +++ } \ +++} while (0) +++ +++#define FP_CLS_NORMAL 0 +++#define FP_CLS_ZERO 1 +++#define FP_CLS_INF 2 +++#define FP_CLS_NAN 3 +++ +++#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) +++ +++#include "op-1.h" +++#include "op-2.h" +++#include "op-4.h" +++#include "op-8.h" +++#include "op-common.h" +++ +++/* Sigh. Silly things longlong.h needs. */ +++#define UWtype _FP_W_TYPE +++#define W_TYPE_SIZE _FP_W_TYPE_SIZE +++ +++typedef int QItype __attribute__((mode(QI))); +++typedef int SItype __attribute__((mode(SI))); +++typedef int DItype __attribute__((mode(DI))); +++typedef unsigned int UQItype __attribute__((mode(QI))); +++typedef unsigned int USItype __attribute__((mode(SI))); +++typedef unsigned int UDItype __attribute__((mode(DI))); +++#if _FP_W_TYPE_SIZE == 32 +++typedef unsigned int UHWtype __attribute__((mode(HI))); +++#elif _FP_W_TYPE_SIZE == 64 +++typedef USItype UHWtype; +++#endif +++ +++#ifndef CMPtype +++#define CMPtype int +++#endif +++ +++#define SI_BITS (__CHAR_BIT__ * (int)sizeof(SItype)) +++#define DI_BITS (__CHAR_BIT__ * (int)sizeof(DItype)) +++ +++#ifndef umul_ppmm +++#include "longlong.h" +++#endif +++ +++#ifdef _LIBC +++#include +++#else +++extern void abort (void); +++#endif +++ +++#endif +diff --git a/packages/uClibc/0.9.31/uClibc-0.9.31-workaround-GCC-PR32219.patch b/packages/uClibc/0.9.31/uClibc-0.9.31-workaround-GCC-PR32219.patch +new file mode 100644 +index 00000000..242a5264 +--- /dev/null ++++ b/packages/uClibc/0.9.31/uClibc-0.9.31-workaround-GCC-PR32219.patch +@@ -0,0 +1,57 @@ ++From 2e53dd645d5348f207cec7f8595969dc566c5a55 Mon Sep 17 00:00:00 2001 ++From: Denys Vlasenko ++Date: Mon, 17 May 2010 15:56:19 +0200 ++Subject: [PATCH] workaround GCC PR32219 ++ ++we ended up calling 0 ++Fixes bug #1033 ++ ++Signed-off-by: Denys Vlasenko ++Signed-off-by: Bernhard Reutner-Fischer ++--- ++ libc/misc/internals/__uClibc_main.c | 15 +++++++++++++-- ++ 1 files changed, 13 insertions(+), 2 deletions(-) ++ ++diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c ++index f9e1244..4ee4443 100644 ++--- a/libc/misc/internals/__uClibc_main.c +++++ b/libc/misc/internals/__uClibc_main.c ++@@ -105,6 +105,17 @@ _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *__buffer, ++ ++ #endif /* !SHARED */ ++ +++/* Defeat compiler optimization which assumes function addresses are never NULL */ +++static __always_inline int not_null_ptr(const void *p) +++{ +++ const void *q; +++ __asm__ ("" +++ : "=r" (q) /* output */ +++ : "0" (p) /* input */ +++ ); +++ return q != 0; +++} +++ ++ /* ++ * Prototypes. ++ */ ++@@ -254,7 +265,7 @@ void __uClibc_init(void) ++ ++ #ifdef __UCLIBC_HAS_LOCALE__ ++ /* Initialize the global locale structure. */ ++- if (likely(_locale_init!=NULL)) +++ if (likely(not_null_ptr(_locale_init))) ++ _locale_init(); ++ #endif ++ ++@@ -264,7 +275,7 @@ void __uClibc_init(void) ++ * Thus we get a nice size savings because the stdio functions ++ * won't be pulled into the final static binary unless used. ++ */ ++- if (likely(_stdio_init != NULL)) +++ if (likely(not_null_ptr(_stdio_init))) ++ _stdio_init(); ++ ++ } ++-- ++1.7.1 ++ +diff --git a/packages/uClibc/0.9.31/version.desc b/packages/uClibc/0.9.31/version.desc +new file mode 100644 +index 00000000..fcfe3891 +--- /dev/null ++++ b/packages/uClibc/0.9.31/version.desc +@@ -0,0 +1 @@ ++obsolete='yes' +diff --git a/packages/uClibc/package.desc b/packages/uClibc/package.desc +index 7035b96b..68c189ed 100644 +--- a/packages/uClibc/package.desc ++++ b/packages/uClibc/package.desc +@@ -4,5 +4,5 @@ preferred='uClibc-ng' + origin='uclibc.org' + repository='git git://git.busybox.net/uClibc' + mirrors='http://www.uclibc.org/downloads http://www.uclibc.org/downloads/old-releases' +-milestones='0.9.33.2 1.0.0 1.0.15 1.0.21 1.0.23' ++milestones='0.9.31 0.9.33.2 1.0.0 1.0.15 1.0.21 1.0.23' + archive_formats='.tar.xz .tar.bz2' +diff --git a/scripts/build/libc/uClibc.sh b/scripts/build/libc/uClibc.sh +index 5c04b328..d06cea5d 100644 +--- a/scripts/build/libc/uClibc.sh ++++ b/scripts/build/libc/uClibc.sh +@@ -77,6 +77,7 @@ uClibc_backend_once() + # - We do _not_ want to strip anything for now, in case we specifically + # asked for a debug toolchain, thus the STRIPTOOL= assignment. + make_args=( CROSS_COMPILE="${CT_TARGET}-" \ ++ CROSS="${CT_TARGET}-" \ + HOSTCC="${CT_BUILD}-gcc" \ + PREFIX="${multi_root}/" \ + MULTILIB_DIR="${multilib_dir}" \ +-- +2.25.1 + diff --git a/toolchains/opendingux/packages/toolchain/uclibc.config b/toolchains/opendingux/packages/toolchain/uclibc.config new file mode 100644 index 0000000..d244135 --- /dev/null +++ b/toolchains/opendingux/packages/toolchain/uclibc.config @@ -0,0 +1,27 @@ +FORCE_SHAREABLE_TEXT_SEGMENTS=y +# UCLIBC_STATIC_LDCONFIG is not set +MALLOC_GLIBC_COMPAT=y +UCLIBC_SUSV3_LEGACY=y +UCLIBC_SUSV4_LEGACY=y +# UCLIBC_HAS_SHADOW is not set +UCLIBC_HAS_LIBUTIL=y + +# UCLIBC_LINUX_MODULE_24 is not set +# UCLIBC_HAS_XATTR is not set +# UCLIBC_HAS_PROFILING is not set +UCLIBC_USE_NETLINK=y + +# UCLIBC_HAS_CTYPE_UNSAFE is not set +UCLIBC_HAS_CTYPE_ENFORCED=y +UCLIBC_HAS_HEXADECIMAL_FLOATS=y +UCLIBC_HAS_GLIBC_CUSTOM_PRINTF=y +UCLIBC_HAS_SCANF_GLIBC_A_FLAG=y +UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y +UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y +UCLIBC_HAS_PRINTF_M_SPEC=y +# UCLIBC_HAS_GNU_GETSUBOPT is not set + +UCLIBC_HAS_GNU_GLOB=y +UCLIBC_HAS_UTMPX=y + +UCLIBC_BUILD_NOW=y diff --git a/toolchains/opendingux/packages/zlib/build.sh b/toolchains/opendingux/packages/zlib/build.sh new file mode 100755 index 0000000..b3f01b8 --- /dev/null +++ b/toolchains/opendingux/packages/zlib/build.sh @@ -0,0 +1,20 @@ +#! /bin/sh + +# Stick with toolchain version +ZLIB_VERSION=1.2.5 +ZLIB_SHA256=6064e52e513facb0fbb7998c6413406cf253cfb986063d68f4771c2bf7a3f958 + +PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +HELPERS_DIR=$PACKAGE_DIR/../.. +. $HELPERS_DIR/functions.sh + +do_make_bdir + +do_http_fetch zlib "http://www.zlib.net/fossils/zlib-${ZLIB_VERSION}.tar.gz" 'tar xzf' "sha256:${ZLIB_SHA256}" + +# Enable shared objects +./configure --prefix=$PREFIX --shared +do_make +do_make install + +do_clean_bdir diff --git a/workers/opendingux/Dockerfile.m4 b/workers/opendingux/Dockerfile.m4 new file mode 100644 index 0000000..9c38e69 --- /dev/null +++ b/workers/opendingux/Dockerfile.m4 @@ -0,0 +1,22 @@ +FROM toolchains/opendingux AS toolchain + +m4_include(`paths.m4')m4_dnl + +m4_include(`debian-builder-base.m4')m4_dnl + +ENV DINGUX_TOOLCHAIN=/opt/dingux-toolchain HOST=mipsel-unknown-linux-uclibc + +COPY --from=toolchain ${DINGUX_TOOLCHAIN} ${DINGUX_TOOLCHAIN}/ + +ENV PREFIX=${DINGUX_TOOLCHAIN}/${HOST}/sysroot/usr + +# We add PATH here for *-config and platform specific binaries +ENV \ + def_binaries(`${DINGUX_TOOLCHAIN}/bin/${HOST}-', `ar, as, c++filt, ld, nm, objcopy, objdump, ranlib, readelf, strings, strip') \ + def_binaries(`${DINGUX_TOOLCHAIN}/bin/${HOST}-', `gcc, cpp, c++') \ + CC=${DINGUX_TOOLCHAIN}/bin/$HOST-gcc \ + def_aclocal(`${PREFIX}') \ + def_pkg_config(`${PREFIX}') \ + PATH=$PATH:${PREFIX}/bin + +m4_include(`run-buildbot.m4')m4_dnl