OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/tags/or1ksim/or1ksim-0.5.0rc1/testsuite/test-code-or1k/testfloat
    from Rev 346 to Rev 347
    Reverse comparison

Rev 346 → Rev 347

/Makefile.in
0,0 → 1,858
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
 
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
 
@SET_MAKE@
 
# Makefile.am for or1ksim testsuite CPU test program: testsoftfloat, testfloat
 
# Copyright (C) ORSoC AB, 2010
 
# Contributor Julius Baxter <julius.baxter@orsoc.se>
 
# This file is part of OpenRISC 1000 Architectural Simulator.
 
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
 
# This program 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 General Public License for
# more details.
 
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http:#www.gnu.org/licenses/>. */
 
# -----------------------------------------------------------------------------
# This code is commented throughout for use with Doxygen.
# -----------------------------------------------------------------------------
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
check_PROGRAMS = testsoftfloat$(EXEEXT) testfloat$(EXEEXT)
subdir = testfloat
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__objects_1 = testfloat-fail.$(OBJEXT) testfloat-random.$(OBJEXT) \
testfloat-writeHex.$(OBJEXT) testfloat-softfloat.$(OBJEXT) \
testfloat-testCases.$(OBJEXT) testfloat-testLoops.$(OBJEXT)
am_testfloat_OBJECTS = $(am__objects_1) testfloat-systmodes.$(OBJEXT) \
testfloat-systflags.$(OBJEXT) systfloat.$(OBJEXT) \
testfloat-testFunction.$(OBJEXT) testfloat-testfloat.$(OBJEXT)
testfloat_OBJECTS = $(am_testfloat_OBJECTS)
testfloat_DEPENDENCIES = ../except/except.lo ../support/libsupport.la
testfloat_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(testfloat_CFLAGS) \
$(CFLAGS) $(testfloat_LDFLAGS) $(LDFLAGS) -o $@
am__objects_2 = testsoftfloat-fail.$(OBJEXT) \
testsoftfloat-random.$(OBJEXT) \
testsoftfloat-writeHex.$(OBJEXT) \
testsoftfloat-softfloat.$(OBJEXT) \
testsoftfloat-testCases.$(OBJEXT) \
testsoftfloat-testLoops.$(OBJEXT)
am_testsoftfloat_OBJECTS = $(am__objects_2) \
testsoftfloat-slowfloat.$(OBJEXT) \
testsoftfloat-testsoftfloat.$(OBJEXT)
testsoftfloat_OBJECTS = $(am_testsoftfloat_OBJECTS)
testsoftfloat_DEPENDENCIES = ../except/except.lo \
../support/libsupport.la
testsoftfloat_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(testsoftfloat_CFLAGS) \
$(CFLAGS) $(testsoftfloat_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/../../depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
LTCPPASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(testfloat_SOURCES) $(testsoftfloat_SOURCES)
DIST_SOURCES = $(testfloat_SOURCES) $(testsoftfloat_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SIM = @SIM@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
common_testfloat_sources = milieu.h \
or1k-gcc.h \
fail.h \
fail.c \
random.h \
random.c \
writeHex.h \
writeHex.c \
softfloat.h \
softfloat.c \
testCases.h \
testCases.c \
testLoops.h \
testLoops.c
 
testsoftfloat_SOURCES = $(common_testfloat_sources) \
slowfloat.h \
slowfloat.c \
testsoftfloat.c
 
testsoftfloat_CFLAGS = -O3
testsoftfloat_LDFLAGS = -T$(srcdir)/../default.ld -lgcc
testsoftfloat_LDADD = ../except/except.lo \
../support/libsupport.la
 
testfloat_SOURCES = $(common_testfloat_sources) \
systmodes.h \
systmodes.c \
systflags.h \
systflags.c \
systfloat.h \
systfloat.S \
testFunction.h \
testFunction.c \
testfloat.c
 
testfloat_CFLAGS = -O2
testfloat_LDFLAGS = -T$(srcdir)/../default.ld -lgcc
testfloat_LDADD = ../except/except.lo \
../support/libsupport.la
 
all: all-am
 
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu testfloat/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu testfloat/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
 
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
 
clean-checkPROGRAMS:
@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
testfloat$(EXEEXT): $(testfloat_OBJECTS) $(testfloat_DEPENDENCIES)
@rm -f testfloat$(EXEEXT)
$(testfloat_LINK) $(testfloat_OBJECTS) $(testfloat_LDADD) $(LIBS)
testsoftfloat$(EXEEXT): $(testsoftfloat_OBJECTS) $(testsoftfloat_DEPENDENCIES)
@rm -f testsoftfloat$(EXEEXT)
$(testsoftfloat_LINK) $(testsoftfloat_OBJECTS) $(testsoftfloat_LDADD) $(LIBS)
 
mostlyclean-compile:
-rm -f *.$(OBJEXT)
 
distclean-compile:
-rm -f *.tab.c
 
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/systfloat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-fail.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-random.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-softfloat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-systflags.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-systmodes.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-testCases.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-testFunction.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-testLoops.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-testfloat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfloat-writeHex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsoftfloat-fail.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsoftfloat-random.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsoftfloat-slowfloat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsoftfloat-softfloat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsoftfloat-testCases.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsoftfloat-testLoops.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsoftfloat-testsoftfloat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsoftfloat-writeHex.Po@am__quote@
 
.S.o:
@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCCAS_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ $<
 
.S.obj:
@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCCAS_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
.S.lo:
@am__fastdepCCAS_TRUE@ $(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCCAS_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCCAS_FALSE@ $(LTCPPASCOMPILE) -c -o $@ $<
 
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
 
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
 
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
 
testfloat-fail.o: fail.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-fail.o -MD -MP -MF $(DEPDIR)/testfloat-fail.Tpo -c -o testfloat-fail.o `test -f 'fail.c' || echo '$(srcdir)/'`fail.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-fail.Tpo $(DEPDIR)/testfloat-fail.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fail.c' object='testfloat-fail.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-fail.o `test -f 'fail.c' || echo '$(srcdir)/'`fail.c
 
testfloat-fail.obj: fail.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-fail.obj -MD -MP -MF $(DEPDIR)/testfloat-fail.Tpo -c -o testfloat-fail.obj `if test -f 'fail.c'; then $(CYGPATH_W) 'fail.c'; else $(CYGPATH_W) '$(srcdir)/fail.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-fail.Tpo $(DEPDIR)/testfloat-fail.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fail.c' object='testfloat-fail.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-fail.obj `if test -f 'fail.c'; then $(CYGPATH_W) 'fail.c'; else $(CYGPATH_W) '$(srcdir)/fail.c'; fi`
 
testfloat-random.o: random.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-random.o -MD -MP -MF $(DEPDIR)/testfloat-random.Tpo -c -o testfloat-random.o `test -f 'random.c' || echo '$(srcdir)/'`random.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-random.Tpo $(DEPDIR)/testfloat-random.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='random.c' object='testfloat-random.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-random.o `test -f 'random.c' || echo '$(srcdir)/'`random.c
 
testfloat-random.obj: random.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-random.obj -MD -MP -MF $(DEPDIR)/testfloat-random.Tpo -c -o testfloat-random.obj `if test -f 'random.c'; then $(CYGPATH_W) 'random.c'; else $(CYGPATH_W) '$(srcdir)/random.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-random.Tpo $(DEPDIR)/testfloat-random.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='random.c' object='testfloat-random.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-random.obj `if test -f 'random.c'; then $(CYGPATH_W) 'random.c'; else $(CYGPATH_W) '$(srcdir)/random.c'; fi`
 
testfloat-writeHex.o: writeHex.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-writeHex.o -MD -MP -MF $(DEPDIR)/testfloat-writeHex.Tpo -c -o testfloat-writeHex.o `test -f 'writeHex.c' || echo '$(srcdir)/'`writeHex.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-writeHex.Tpo $(DEPDIR)/testfloat-writeHex.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writeHex.c' object='testfloat-writeHex.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-writeHex.o `test -f 'writeHex.c' || echo '$(srcdir)/'`writeHex.c
 
testfloat-writeHex.obj: writeHex.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-writeHex.obj -MD -MP -MF $(DEPDIR)/testfloat-writeHex.Tpo -c -o testfloat-writeHex.obj `if test -f 'writeHex.c'; then $(CYGPATH_W) 'writeHex.c'; else $(CYGPATH_W) '$(srcdir)/writeHex.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-writeHex.Tpo $(DEPDIR)/testfloat-writeHex.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writeHex.c' object='testfloat-writeHex.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-writeHex.obj `if test -f 'writeHex.c'; then $(CYGPATH_W) 'writeHex.c'; else $(CYGPATH_W) '$(srcdir)/writeHex.c'; fi`
 
testfloat-softfloat.o: softfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-softfloat.o -MD -MP -MF $(DEPDIR)/testfloat-softfloat.Tpo -c -o testfloat-softfloat.o `test -f 'softfloat.c' || echo '$(srcdir)/'`softfloat.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-softfloat.Tpo $(DEPDIR)/testfloat-softfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='softfloat.c' object='testfloat-softfloat.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-softfloat.o `test -f 'softfloat.c' || echo '$(srcdir)/'`softfloat.c
 
testfloat-softfloat.obj: softfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-softfloat.obj -MD -MP -MF $(DEPDIR)/testfloat-softfloat.Tpo -c -o testfloat-softfloat.obj `if test -f 'softfloat.c'; then $(CYGPATH_W) 'softfloat.c'; else $(CYGPATH_W) '$(srcdir)/softfloat.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-softfloat.Tpo $(DEPDIR)/testfloat-softfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='softfloat.c' object='testfloat-softfloat.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-softfloat.obj `if test -f 'softfloat.c'; then $(CYGPATH_W) 'softfloat.c'; else $(CYGPATH_W) '$(srcdir)/softfloat.c'; fi`
 
testfloat-testCases.o: testCases.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-testCases.o -MD -MP -MF $(DEPDIR)/testfloat-testCases.Tpo -c -o testfloat-testCases.o `test -f 'testCases.c' || echo '$(srcdir)/'`testCases.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-testCases.Tpo $(DEPDIR)/testfloat-testCases.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testCases.c' object='testfloat-testCases.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-testCases.o `test -f 'testCases.c' || echo '$(srcdir)/'`testCases.c
 
testfloat-testCases.obj: testCases.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-testCases.obj -MD -MP -MF $(DEPDIR)/testfloat-testCases.Tpo -c -o testfloat-testCases.obj `if test -f 'testCases.c'; then $(CYGPATH_W) 'testCases.c'; else $(CYGPATH_W) '$(srcdir)/testCases.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-testCases.Tpo $(DEPDIR)/testfloat-testCases.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testCases.c' object='testfloat-testCases.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-testCases.obj `if test -f 'testCases.c'; then $(CYGPATH_W) 'testCases.c'; else $(CYGPATH_W) '$(srcdir)/testCases.c'; fi`
 
testfloat-testLoops.o: testLoops.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-testLoops.o -MD -MP -MF $(DEPDIR)/testfloat-testLoops.Tpo -c -o testfloat-testLoops.o `test -f 'testLoops.c' || echo '$(srcdir)/'`testLoops.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-testLoops.Tpo $(DEPDIR)/testfloat-testLoops.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testLoops.c' object='testfloat-testLoops.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-testLoops.o `test -f 'testLoops.c' || echo '$(srcdir)/'`testLoops.c
 
testfloat-testLoops.obj: testLoops.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-testLoops.obj -MD -MP -MF $(DEPDIR)/testfloat-testLoops.Tpo -c -o testfloat-testLoops.obj `if test -f 'testLoops.c'; then $(CYGPATH_W) 'testLoops.c'; else $(CYGPATH_W) '$(srcdir)/testLoops.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-testLoops.Tpo $(DEPDIR)/testfloat-testLoops.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testLoops.c' object='testfloat-testLoops.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-testLoops.obj `if test -f 'testLoops.c'; then $(CYGPATH_W) 'testLoops.c'; else $(CYGPATH_W) '$(srcdir)/testLoops.c'; fi`
 
testfloat-systmodes.o: systmodes.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-systmodes.o -MD -MP -MF $(DEPDIR)/testfloat-systmodes.Tpo -c -o testfloat-systmodes.o `test -f 'systmodes.c' || echo '$(srcdir)/'`systmodes.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-systmodes.Tpo $(DEPDIR)/testfloat-systmodes.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='systmodes.c' object='testfloat-systmodes.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-systmodes.o `test -f 'systmodes.c' || echo '$(srcdir)/'`systmodes.c
 
testfloat-systmodes.obj: systmodes.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-systmodes.obj -MD -MP -MF $(DEPDIR)/testfloat-systmodes.Tpo -c -o testfloat-systmodes.obj `if test -f 'systmodes.c'; then $(CYGPATH_W) 'systmodes.c'; else $(CYGPATH_W) '$(srcdir)/systmodes.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-systmodes.Tpo $(DEPDIR)/testfloat-systmodes.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='systmodes.c' object='testfloat-systmodes.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-systmodes.obj `if test -f 'systmodes.c'; then $(CYGPATH_W) 'systmodes.c'; else $(CYGPATH_W) '$(srcdir)/systmodes.c'; fi`
 
testfloat-systflags.o: systflags.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-systflags.o -MD -MP -MF $(DEPDIR)/testfloat-systflags.Tpo -c -o testfloat-systflags.o `test -f 'systflags.c' || echo '$(srcdir)/'`systflags.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-systflags.Tpo $(DEPDIR)/testfloat-systflags.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='systflags.c' object='testfloat-systflags.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-systflags.o `test -f 'systflags.c' || echo '$(srcdir)/'`systflags.c
 
testfloat-systflags.obj: systflags.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-systflags.obj -MD -MP -MF $(DEPDIR)/testfloat-systflags.Tpo -c -o testfloat-systflags.obj `if test -f 'systflags.c'; then $(CYGPATH_W) 'systflags.c'; else $(CYGPATH_W) '$(srcdir)/systflags.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-systflags.Tpo $(DEPDIR)/testfloat-systflags.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='systflags.c' object='testfloat-systflags.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-systflags.obj `if test -f 'systflags.c'; then $(CYGPATH_W) 'systflags.c'; else $(CYGPATH_W) '$(srcdir)/systflags.c'; fi`
 
testfloat-testFunction.o: testFunction.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-testFunction.o -MD -MP -MF $(DEPDIR)/testfloat-testFunction.Tpo -c -o testfloat-testFunction.o `test -f 'testFunction.c' || echo '$(srcdir)/'`testFunction.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-testFunction.Tpo $(DEPDIR)/testfloat-testFunction.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testFunction.c' object='testfloat-testFunction.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-testFunction.o `test -f 'testFunction.c' || echo '$(srcdir)/'`testFunction.c
 
testfloat-testFunction.obj: testFunction.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-testFunction.obj -MD -MP -MF $(DEPDIR)/testfloat-testFunction.Tpo -c -o testfloat-testFunction.obj `if test -f 'testFunction.c'; then $(CYGPATH_W) 'testFunction.c'; else $(CYGPATH_W) '$(srcdir)/testFunction.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-testFunction.Tpo $(DEPDIR)/testfloat-testFunction.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testFunction.c' object='testfloat-testFunction.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-testFunction.obj `if test -f 'testFunction.c'; then $(CYGPATH_W) 'testFunction.c'; else $(CYGPATH_W) '$(srcdir)/testFunction.c'; fi`
 
testfloat-testfloat.o: testfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-testfloat.o -MD -MP -MF $(DEPDIR)/testfloat-testfloat.Tpo -c -o testfloat-testfloat.o `test -f 'testfloat.c' || echo '$(srcdir)/'`testfloat.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-testfloat.Tpo $(DEPDIR)/testfloat-testfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testfloat.c' object='testfloat-testfloat.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-testfloat.o `test -f 'testfloat.c' || echo '$(srcdir)/'`testfloat.c
 
testfloat-testfloat.obj: testfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -MT testfloat-testfloat.obj -MD -MP -MF $(DEPDIR)/testfloat-testfloat.Tpo -c -o testfloat-testfloat.obj `if test -f 'testfloat.c'; then $(CYGPATH_W) 'testfloat.c'; else $(CYGPATH_W) '$(srcdir)/testfloat.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testfloat-testfloat.Tpo $(DEPDIR)/testfloat-testfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testfloat.c' object='testfloat-testfloat.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testfloat_CFLAGS) $(CFLAGS) -c -o testfloat-testfloat.obj `if test -f 'testfloat.c'; then $(CYGPATH_W) 'testfloat.c'; else $(CYGPATH_W) '$(srcdir)/testfloat.c'; fi`
 
testsoftfloat-fail.o: fail.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-fail.o -MD -MP -MF $(DEPDIR)/testsoftfloat-fail.Tpo -c -o testsoftfloat-fail.o `test -f 'fail.c' || echo '$(srcdir)/'`fail.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-fail.Tpo $(DEPDIR)/testsoftfloat-fail.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fail.c' object='testsoftfloat-fail.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-fail.o `test -f 'fail.c' || echo '$(srcdir)/'`fail.c
 
testsoftfloat-fail.obj: fail.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-fail.obj -MD -MP -MF $(DEPDIR)/testsoftfloat-fail.Tpo -c -o testsoftfloat-fail.obj `if test -f 'fail.c'; then $(CYGPATH_W) 'fail.c'; else $(CYGPATH_W) '$(srcdir)/fail.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-fail.Tpo $(DEPDIR)/testsoftfloat-fail.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fail.c' object='testsoftfloat-fail.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-fail.obj `if test -f 'fail.c'; then $(CYGPATH_W) 'fail.c'; else $(CYGPATH_W) '$(srcdir)/fail.c'; fi`
 
testsoftfloat-random.o: random.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-random.o -MD -MP -MF $(DEPDIR)/testsoftfloat-random.Tpo -c -o testsoftfloat-random.o `test -f 'random.c' || echo '$(srcdir)/'`random.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-random.Tpo $(DEPDIR)/testsoftfloat-random.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='random.c' object='testsoftfloat-random.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-random.o `test -f 'random.c' || echo '$(srcdir)/'`random.c
 
testsoftfloat-random.obj: random.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-random.obj -MD -MP -MF $(DEPDIR)/testsoftfloat-random.Tpo -c -o testsoftfloat-random.obj `if test -f 'random.c'; then $(CYGPATH_W) 'random.c'; else $(CYGPATH_W) '$(srcdir)/random.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-random.Tpo $(DEPDIR)/testsoftfloat-random.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='random.c' object='testsoftfloat-random.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-random.obj `if test -f 'random.c'; then $(CYGPATH_W) 'random.c'; else $(CYGPATH_W) '$(srcdir)/random.c'; fi`
 
testsoftfloat-writeHex.o: writeHex.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-writeHex.o -MD -MP -MF $(DEPDIR)/testsoftfloat-writeHex.Tpo -c -o testsoftfloat-writeHex.o `test -f 'writeHex.c' || echo '$(srcdir)/'`writeHex.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-writeHex.Tpo $(DEPDIR)/testsoftfloat-writeHex.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writeHex.c' object='testsoftfloat-writeHex.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-writeHex.o `test -f 'writeHex.c' || echo '$(srcdir)/'`writeHex.c
 
testsoftfloat-writeHex.obj: writeHex.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-writeHex.obj -MD -MP -MF $(DEPDIR)/testsoftfloat-writeHex.Tpo -c -o testsoftfloat-writeHex.obj `if test -f 'writeHex.c'; then $(CYGPATH_W) 'writeHex.c'; else $(CYGPATH_W) '$(srcdir)/writeHex.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-writeHex.Tpo $(DEPDIR)/testsoftfloat-writeHex.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writeHex.c' object='testsoftfloat-writeHex.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-writeHex.obj `if test -f 'writeHex.c'; then $(CYGPATH_W) 'writeHex.c'; else $(CYGPATH_W) '$(srcdir)/writeHex.c'; fi`
 
testsoftfloat-softfloat.o: softfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-softfloat.o -MD -MP -MF $(DEPDIR)/testsoftfloat-softfloat.Tpo -c -o testsoftfloat-softfloat.o `test -f 'softfloat.c' || echo '$(srcdir)/'`softfloat.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-softfloat.Tpo $(DEPDIR)/testsoftfloat-softfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='softfloat.c' object='testsoftfloat-softfloat.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-softfloat.o `test -f 'softfloat.c' || echo '$(srcdir)/'`softfloat.c
 
testsoftfloat-softfloat.obj: softfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-softfloat.obj -MD -MP -MF $(DEPDIR)/testsoftfloat-softfloat.Tpo -c -o testsoftfloat-softfloat.obj `if test -f 'softfloat.c'; then $(CYGPATH_W) 'softfloat.c'; else $(CYGPATH_W) '$(srcdir)/softfloat.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-softfloat.Tpo $(DEPDIR)/testsoftfloat-softfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='softfloat.c' object='testsoftfloat-softfloat.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-softfloat.obj `if test -f 'softfloat.c'; then $(CYGPATH_W) 'softfloat.c'; else $(CYGPATH_W) '$(srcdir)/softfloat.c'; fi`
 
testsoftfloat-testCases.o: testCases.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-testCases.o -MD -MP -MF $(DEPDIR)/testsoftfloat-testCases.Tpo -c -o testsoftfloat-testCases.o `test -f 'testCases.c' || echo '$(srcdir)/'`testCases.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-testCases.Tpo $(DEPDIR)/testsoftfloat-testCases.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testCases.c' object='testsoftfloat-testCases.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-testCases.o `test -f 'testCases.c' || echo '$(srcdir)/'`testCases.c
 
testsoftfloat-testCases.obj: testCases.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-testCases.obj -MD -MP -MF $(DEPDIR)/testsoftfloat-testCases.Tpo -c -o testsoftfloat-testCases.obj `if test -f 'testCases.c'; then $(CYGPATH_W) 'testCases.c'; else $(CYGPATH_W) '$(srcdir)/testCases.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-testCases.Tpo $(DEPDIR)/testsoftfloat-testCases.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testCases.c' object='testsoftfloat-testCases.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-testCases.obj `if test -f 'testCases.c'; then $(CYGPATH_W) 'testCases.c'; else $(CYGPATH_W) '$(srcdir)/testCases.c'; fi`
 
testsoftfloat-testLoops.o: testLoops.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-testLoops.o -MD -MP -MF $(DEPDIR)/testsoftfloat-testLoops.Tpo -c -o testsoftfloat-testLoops.o `test -f 'testLoops.c' || echo '$(srcdir)/'`testLoops.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-testLoops.Tpo $(DEPDIR)/testsoftfloat-testLoops.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testLoops.c' object='testsoftfloat-testLoops.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-testLoops.o `test -f 'testLoops.c' || echo '$(srcdir)/'`testLoops.c
 
testsoftfloat-testLoops.obj: testLoops.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-testLoops.obj -MD -MP -MF $(DEPDIR)/testsoftfloat-testLoops.Tpo -c -o testsoftfloat-testLoops.obj `if test -f 'testLoops.c'; then $(CYGPATH_W) 'testLoops.c'; else $(CYGPATH_W) '$(srcdir)/testLoops.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-testLoops.Tpo $(DEPDIR)/testsoftfloat-testLoops.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testLoops.c' object='testsoftfloat-testLoops.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-testLoops.obj `if test -f 'testLoops.c'; then $(CYGPATH_W) 'testLoops.c'; else $(CYGPATH_W) '$(srcdir)/testLoops.c'; fi`
 
testsoftfloat-slowfloat.o: slowfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-slowfloat.o -MD -MP -MF $(DEPDIR)/testsoftfloat-slowfloat.Tpo -c -o testsoftfloat-slowfloat.o `test -f 'slowfloat.c' || echo '$(srcdir)/'`slowfloat.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-slowfloat.Tpo $(DEPDIR)/testsoftfloat-slowfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slowfloat.c' object='testsoftfloat-slowfloat.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-slowfloat.o `test -f 'slowfloat.c' || echo '$(srcdir)/'`slowfloat.c
 
testsoftfloat-slowfloat.obj: slowfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-slowfloat.obj -MD -MP -MF $(DEPDIR)/testsoftfloat-slowfloat.Tpo -c -o testsoftfloat-slowfloat.obj `if test -f 'slowfloat.c'; then $(CYGPATH_W) 'slowfloat.c'; else $(CYGPATH_W) '$(srcdir)/slowfloat.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-slowfloat.Tpo $(DEPDIR)/testsoftfloat-slowfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='slowfloat.c' object='testsoftfloat-slowfloat.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-slowfloat.obj `if test -f 'slowfloat.c'; then $(CYGPATH_W) 'slowfloat.c'; else $(CYGPATH_W) '$(srcdir)/slowfloat.c'; fi`
 
testsoftfloat-testsoftfloat.o: testsoftfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-testsoftfloat.o -MD -MP -MF $(DEPDIR)/testsoftfloat-testsoftfloat.Tpo -c -o testsoftfloat-testsoftfloat.o `test -f 'testsoftfloat.c' || echo '$(srcdir)/'`testsoftfloat.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-testsoftfloat.Tpo $(DEPDIR)/testsoftfloat-testsoftfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testsoftfloat.c' object='testsoftfloat-testsoftfloat.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-testsoftfloat.o `test -f 'testsoftfloat.c' || echo '$(srcdir)/'`testsoftfloat.c
 
testsoftfloat-testsoftfloat.obj: testsoftfloat.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -MT testsoftfloat-testsoftfloat.obj -MD -MP -MF $(DEPDIR)/testsoftfloat-testsoftfloat.Tpo -c -o testsoftfloat-testsoftfloat.obj `if test -f 'testsoftfloat.c'; then $(CYGPATH_W) 'testsoftfloat.c'; else $(CYGPATH_W) '$(srcdir)/testsoftfloat.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/testsoftfloat-testsoftfloat.Tpo $(DEPDIR)/testsoftfloat-testsoftfloat.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testsoftfloat.c' object='testsoftfloat-testsoftfloat.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(testsoftfloat_CFLAGS) $(CFLAGS) -c -o testsoftfloat-testsoftfloat.obj `if test -f 'testsoftfloat.c'; then $(CYGPATH_W) 'testsoftfloat.c'; else $(CYGPATH_W) '$(srcdir)/testsoftfloat.c'; fi`
 
mostlyclean-libtool:
-rm -f *.lo
 
clean-libtool:
-rm -rf .libs _libs
 
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
 
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
 
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
 
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
 
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
 
clean-generic:
 
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
 
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
 
clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
mostlyclean-am
 
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
 
dvi: dvi-am
 
dvi-am:
 
html: html-am
 
html-am:
 
info: info-am
 
info-am:
 
install-data-am:
 
install-dvi: install-dvi-am
 
install-dvi-am:
 
install-exec-am:
 
install-html: install-html-am
 
install-html-am:
 
install-info: install-info-am
 
install-info-am:
 
install-man:
 
install-pdf: install-pdf-am
 
install-pdf-am:
 
install-ps: install-ps-am
 
install-ps-am:
 
installcheck-am:
 
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
 
mostlyclean: mostlyclean-am
 
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
 
pdf: pdf-am
 
pdf-am:
 
ps: ps-am
 
ps-am:
 
uninstall-am:
 
.MAKE: check-am install-am install-strip
 
.PHONY: CTAGS GTAGS all all-am check check-am clean \
clean-checkPROGRAMS clean-generic clean-libtool ctags \
distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am
 
 
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
/systfloat.S
0,0 → 1,161
/* =============================================================================
 
This GNU assembler source file is part of TestFloat, Release 2a, a package
of programs for testing the correctness of floating-point arithmetic
complying to the IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite. Updated for GCC 4.5.1.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
============================================================================= */
 
.text
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_int32_to_float32
syst_int32_to_float32:
lf.itof.s r11, r3
l.jr r9
l.nop
 
 
 
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_to_int32_round_to_zero
syst_float32_to_int32_round_to_zero:
lf.ftoi.s r11, r3
l.jr r9
l.nop
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_to_int32
syst_float32_to_int32:
lf.ftoi.s r11, r3
l.jr r9
l.nop
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_round_to_int
syst_float32_round_to_int:
lf.ftoi.s r11, r3
l.jr r9
l.nop
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_add
syst_float32_add:
lf.add.s r11, r3, r4
l.jr r9
l.nop
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_sub
syst_float32_sub:
lf.sub.s r11, r3, r4
l.jr r9
l.nop
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_mul
syst_float32_mul:
lf.mul.s r11, r3, r4
l.jr r9
l.nop
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_div
syst_float32_div:
lf.div.s r11, r3, r4
l.jr r9
l.nop
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_eq
syst_float32_eq:
lf.sfeq.s r3, r4
l.bnf 1f
l.addi r11, r0, 0
l.addi r11, r0, 1
1: l.jr r9
l.nop
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_le
syst_float32_le:
lf.sfle.s r3, r4
l.bnf 1f
l.addi r11, r0, 0
l.addi r11, r0, 1
1: l.jr r9
l.nop
 
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
.align 4
.global syst_float32_lt
syst_float32_lt:
lf.sflt.s r3, r4
l.bnf 1f
l.addi r11, r0, 0
l.addi r11, r0, 1
1: l.jr r9
l.nop
/testCases.c
0,0 → 1,3693
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
#include "milieu.h"
#include "fail.h"
#include "random.h"
#include "softfloat.h"
#include "testCases.h"
 
typedef struct {
int16 expNum, term1Num, term2Num;
flag done;
} sequenceT;
 
enum {
int32NumP1 = 124
};
 
static const uint32 int32P1[ int32NumP1 ] = {
0x00000000,
0x00000001,
0x00000002,
0x00000004,
0x00000008,
0x00000010,
0x00000020,
0x00000040,
0x00000080,
0x00000100,
0x00000200,
0x00000400,
0x00000800,
0x00001000,
0x00002000,
0x00004000,
0x00008000,
0x00010000,
0x00020000,
0x00040000,
0x00080000,
0x00100000,
0x00200000,
0x00400000,
0x00800000,
0x01000000,
0x02000000,
0x04000000,
0x08000000,
0x10000000,
0x20000000,
0x40000000,
0x80000000,
0xC0000000,
0xE0000000,
0xF0000000,
0xF8000000,
0xFC000000,
0xFE000000,
0xFF000000,
0xFF800000,
0xFFC00000,
0xFFE00000,
0xFFF00000,
0xFFF80000,
0xFFFC0000,
0xFFFE0000,
0xFFFF0000,
0xFFFF8000,
0xFFFFC000,
0xFFFFE000,
0xFFFFF000,
0xFFFFF800,
0xFFFFFC00,
0xFFFFFE00,
0xFFFFFF00,
0xFFFFFF80,
0xFFFFFFC0,
0xFFFFFFE0,
0xFFFFFFF0,
0xFFFFFFF8,
0xFFFFFFFC,
0xFFFFFFFE,
0xFFFFFFFF,
0xFFFFFFFD,
0xFFFFFFFB,
0xFFFFFFF7,
0xFFFFFFEF,
0xFFFFFFDF,
0xFFFFFFBF,
0xFFFFFF7F,
0xFFFFFEFF,
0xFFFFFDFF,
0xFFFFFBFF,
0xFFFFF7FF,
0xFFFFEFFF,
0xFFFFDFFF,
0xFFFFBFFF,
0xFFFF7FFF,
0xFFFEFFFF,
0xFFFDFFFF,
0xFFFBFFFF,
0xFFF7FFFF,
0xFFEFFFFF,
0xFFDFFFFF,
0xFFBFFFFF,
0xFF7FFFFF,
0xFEFFFFFF,
0xFDFFFFFF,
0xFBFFFFFF,
0xF7FFFFFF,
0xEFFFFFFF,
0xDFFFFFFF,
0xBFFFFFFF,
0x7FFFFFFF,
0x3FFFFFFF,
0x1FFFFFFF,
0x0FFFFFFF,
0x07FFFFFF,
0x03FFFFFF,
0x01FFFFFF,
0x00FFFFFF,
0x007FFFFF,
0x003FFFFF,
0x001FFFFF,
0x000FFFFF,
0x0007FFFF,
0x0003FFFF,
0x0001FFFF,
0x0000FFFF,
0x00007FFF,
0x00003FFF,
0x00001FFF,
0x00000FFF,
0x000007FF,
0x000003FF,
0x000001FF,
0x000000FF,
0x0000007F,
0x0000003F,
0x0000001F,
0x0000000F,
0x00000007,
0x00000003
};
 
static int32 int32NextP1( sequenceT *sequencePtr )
{
uint8 termNum;
int32 z;
 
termNum = sequencePtr->term1Num;
z = int32P1[ termNum ];
++termNum;
if ( int32NumP1 <= termNum ) {
termNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->term1Num = termNum;
return (sbits32) z;
 
}
 
static const int32 int32NumP2 = ( int32NumP1 * int32NumP1 + int32NumP1 ) / 2;
 
static int32 int32NextP2( sequenceT *sequencePtr )
{
uint8 term1Num, term2Num;
int32 z;
 
term2Num = sequencePtr->term2Num;
term1Num = sequencePtr->term1Num;
z = int32P1[ term1Num ] + int32P1[ term2Num ];
++term2Num;
if ( int32NumP1 <= term2Num ) {
++term1Num;
if ( int32NumP1 <= term1Num ) {
term1Num = 0;
sequencePtr->done = TRUE;
}
term2Num = term1Num;
sequencePtr->term1Num = term1Num;
}
sequencePtr->term2Num = term2Num;
return (sbits32) z;
 
}
 
static int32 int32RandomP3( void )
{
 
return
(sbits32) (
int32P1[ randomUint8() % int32NumP1 ]
+ int32P1[ randomUint8() % int32NumP1 ]
+ int32P1[ randomUint8() % int32NumP1 ]
);
 
}
 
enum {
int32NumPInfWeightMasks = 29
};
 
static const uint32 int32PInfWeightMasks[ int32NumPInfWeightMasks ] = {
0xFFFFFFFF,
0x7FFFFFFF,
0x3FFFFFFF,
0x1FFFFFFF,
0x0FFFFFFF,
0x07FFFFFF,
0x03FFFFFF,
0x01FFFFFF,
0x00FFFFFF,
0x007FFFFF,
0x003FFFFF,
0x001FFFFF,
0x000FFFFF,
0x0007FFFF,
0x0003FFFF,
0x0001FFFF,
0x0000FFFF,
0x00007FFF,
0x00003FFF,
0x00001FFF,
0x00000FFF,
0x000007FF,
0x000003FF,
0x000001FF,
0x000000FF,
0x0000007F,
0x0000003F,
0x0000001F,
0x0000000F
};
 
static const uint32 int32PInfWeightOffsets[ int32NumPInfWeightMasks ] = {
0x00000000,
0xC0000000,
0xE0000000,
0xF0000000,
0xF8000000,
0xFC000000,
0xFE000000,
0xFF000000,
0xFF800000,
0xFFC00000,
0xFFE00000,
0xFFF00000,
0xFFF80000,
0xFFFC0000,
0xFFFE0000,
0xFFFF0000,
0xFFFF8000,
0xFFFFC000,
0xFFFFE000,
0xFFFFF000,
0xFFFFF800,
0xFFFFFC00,
0xFFFFFE00,
0xFFFFFF00,
0xFFFFFF80,
0xFFFFFFC0,
0xFFFFFFE0,
0xFFFFFFF0,
0xFFFFFFF8
};
 
static int32 int32RandomPInf( void )
{
int8 weightMaskNum;
 
weightMaskNum = randomUint8() % int32NumPInfWeightMasks;
return
(sbits32) (
( randomUint32() & int32PInfWeightMasks[ weightMaskNum ] )
+ int32PInfWeightOffsets[ weightMaskNum ]
);
 
}
 
#ifdef BITS64
 
enum {
int64NumP1 = 252
};
 
static const uint64 int64P1[ int64NumP1 ] = {
LIT64( 0x0000000000000000 ),
LIT64( 0x0000000000000001 ),
LIT64( 0x0000000000000002 ),
LIT64( 0x0000000000000004 ),
LIT64( 0x0000000000000008 ),
LIT64( 0x0000000000000010 ),
LIT64( 0x0000000000000020 ),
LIT64( 0x0000000000000040 ),
LIT64( 0x0000000000000080 ),
LIT64( 0x0000000000000100 ),
LIT64( 0x0000000000000200 ),
LIT64( 0x0000000000000400 ),
LIT64( 0x0000000000000800 ),
LIT64( 0x0000000000001000 ),
LIT64( 0x0000000000002000 ),
LIT64( 0x0000000000004000 ),
LIT64( 0x0000000000008000 ),
LIT64( 0x0000000000010000 ),
LIT64( 0x0000000000020000 ),
LIT64( 0x0000000000040000 ),
LIT64( 0x0000000000080000 ),
LIT64( 0x0000000000100000 ),
LIT64( 0x0000000000200000 ),
LIT64( 0x0000000000400000 ),
LIT64( 0x0000000000800000 ),
LIT64( 0x0000000001000000 ),
LIT64( 0x0000000002000000 ),
LIT64( 0x0000000004000000 ),
LIT64( 0x0000000008000000 ),
LIT64( 0x0000000010000000 ),
LIT64( 0x0000000020000000 ),
LIT64( 0x0000000040000000 ),
LIT64( 0x0000000080000000 ),
LIT64( 0x0000000100000000 ),
LIT64( 0x0000000200000000 ),
LIT64( 0x0000000400000000 ),
LIT64( 0x0000000800000000 ),
LIT64( 0x0000001000000000 ),
LIT64( 0x0000002000000000 ),
LIT64( 0x0000004000000000 ),
LIT64( 0x0000008000000000 ),
LIT64( 0x0000010000000000 ),
LIT64( 0x0000020000000000 ),
LIT64( 0x0000040000000000 ),
LIT64( 0x0000080000000000 ),
LIT64( 0x0000100000000000 ),
LIT64( 0x0000200000000000 ),
LIT64( 0x0000400000000000 ),
LIT64( 0x0000800000000000 ),
LIT64( 0x0001000000000000 ),
LIT64( 0x0002000000000000 ),
LIT64( 0x0004000000000000 ),
LIT64( 0x0008000000000000 ),
LIT64( 0x0010000000000000 ),
LIT64( 0x0020000000000000 ),
LIT64( 0x0040000000000000 ),
LIT64( 0x0080000000000000 ),
LIT64( 0x0100000000000000 ),
LIT64( 0x0200000000000000 ),
LIT64( 0x0400000000000000 ),
LIT64( 0x0800000000000000 ),
LIT64( 0x1000000000000000 ),
LIT64( 0x2000000000000000 ),
LIT64( 0x4000000000000000 ),
LIT64( 0x8000000000000000 ),
LIT64( 0xC000000000000000 ),
LIT64( 0xE000000000000000 ),
LIT64( 0xF000000000000000 ),
LIT64( 0xF800000000000000 ),
LIT64( 0xFC00000000000000 ),
LIT64( 0xFE00000000000000 ),
LIT64( 0xFF00000000000000 ),
LIT64( 0xFF80000000000000 ),
LIT64( 0xFFC0000000000000 ),
LIT64( 0xFFE0000000000000 ),
LIT64( 0xFFF0000000000000 ),
LIT64( 0xFFF8000000000000 ),
LIT64( 0xFFFC000000000000 ),
LIT64( 0xFFFE000000000000 ),
LIT64( 0xFFFF000000000000 ),
LIT64( 0xFFFF800000000000 ),
LIT64( 0xFFFFC00000000000 ),
LIT64( 0xFFFFE00000000000 ),
LIT64( 0xFFFFF00000000000 ),
LIT64( 0xFFFFF80000000000 ),
LIT64( 0xFFFFFC0000000000 ),
LIT64( 0xFFFFFE0000000000 ),
LIT64( 0xFFFFFF0000000000 ),
LIT64( 0xFFFFFF8000000000 ),
LIT64( 0xFFFFFFC000000000 ),
LIT64( 0xFFFFFFE000000000 ),
LIT64( 0xFFFFFFF000000000 ),
LIT64( 0xFFFFFFF800000000 ),
LIT64( 0xFFFFFFFC00000000 ),
LIT64( 0xFFFFFFFE00000000 ),
LIT64( 0xFFFFFFFF00000000 ),
LIT64( 0xFFFFFFFF80000000 ),
LIT64( 0xFFFFFFFFC0000000 ),
LIT64( 0xFFFFFFFFE0000000 ),
LIT64( 0xFFFFFFFFF0000000 ),
LIT64( 0xFFFFFFFFF8000000 ),
LIT64( 0xFFFFFFFFFC000000 ),
LIT64( 0xFFFFFFFFFE000000 ),
LIT64( 0xFFFFFFFFFF000000 ),
LIT64( 0xFFFFFFFFFF800000 ),
LIT64( 0xFFFFFFFFFFC00000 ),
LIT64( 0xFFFFFFFFFFE00000 ),
LIT64( 0xFFFFFFFFFFF00000 ),
LIT64( 0xFFFFFFFFFFF80000 ),
LIT64( 0xFFFFFFFFFFFC0000 ),
LIT64( 0xFFFFFFFFFFFE0000 ),
LIT64( 0xFFFFFFFFFFFF0000 ),
LIT64( 0xFFFFFFFFFFFF8000 ),
LIT64( 0xFFFFFFFFFFFFC000 ),
LIT64( 0xFFFFFFFFFFFFE000 ),
LIT64( 0xFFFFFFFFFFFFF000 ),
LIT64( 0xFFFFFFFFFFFFF800 ),
LIT64( 0xFFFFFFFFFFFFFC00 ),
LIT64( 0xFFFFFFFFFFFFFE00 ),
LIT64( 0xFFFFFFFFFFFFFF00 ),
LIT64( 0xFFFFFFFFFFFFFF80 ),
LIT64( 0xFFFFFFFFFFFFFFC0 ),
LIT64( 0xFFFFFFFFFFFFFFE0 ),
LIT64( 0xFFFFFFFFFFFFFFF0 ),
LIT64( 0xFFFFFFFFFFFFFFF8 ),
LIT64( 0xFFFFFFFFFFFFFFFC ),
LIT64( 0xFFFFFFFFFFFFFFFE ),
LIT64( 0xFFFFFFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFD ),
LIT64( 0xFFFFFFFFFFFFFFFB ),
LIT64( 0xFFFFFFFFFFFFFFF7 ),
LIT64( 0xFFFFFFFFFFFFFFEF ),
LIT64( 0xFFFFFFFFFFFFFFDF ),
LIT64( 0xFFFFFFFFFFFFFFBF ),
LIT64( 0xFFFFFFFFFFFFFF7F ),
LIT64( 0xFFFFFFFFFFFFFEFF ),
LIT64( 0xFFFFFFFFFFFFFDFF ),
LIT64( 0xFFFFFFFFFFFFFBFF ),
LIT64( 0xFFFFFFFFFFFFF7FF ),
LIT64( 0xFFFFFFFFFFFFEFFF ),
LIT64( 0xFFFFFFFFFFFFDFFF ),
LIT64( 0xFFFFFFFFFFFFBFFF ),
LIT64( 0xFFFFFFFFFFFF7FFF ),
LIT64( 0xFFFFFFFFFFFEFFFF ),
LIT64( 0xFFFFFFFFFFFDFFFF ),
LIT64( 0xFFFFFFFFFFFBFFFF ),
LIT64( 0xFFFFFFFFFFF7FFFF ),
LIT64( 0xFFFFFFFFFFEFFFFF ),
LIT64( 0xFFFFFFFFFFDFFFFF ),
LIT64( 0xFFFFFFFFFFBFFFFF ),
LIT64( 0xFFFFFFFFFF7FFFFF ),
LIT64( 0xFFFFFFFFFEFFFFFF ),
LIT64( 0xFFFFFFFFFDFFFFFF ),
LIT64( 0xFFFFFFFFFBFFFFFF ),
LIT64( 0xFFFFFFFFF7FFFFFF ),
LIT64( 0xFFFFFFFFEFFFFFFF ),
LIT64( 0xFFFFFFFFDFFFFFFF ),
LIT64( 0xFFFFFFFFBFFFFFFF ),
LIT64( 0xFFFFFFFF7FFFFFFF ),
LIT64( 0xFFFFFFFEFFFFFFFF ),
LIT64( 0xFFFFFFFDFFFFFFFF ),
LIT64( 0xFFFFFFFBFFFFFFFF ),
LIT64( 0xFFFFFFF7FFFFFFFF ),
LIT64( 0xFFFFFFEFFFFFFFFF ),
LIT64( 0xFFFFFFDFFFFFFFFF ),
LIT64( 0xFFFFFFBFFFFFFFFF ),
LIT64( 0xFFFFFF7FFFFFFFFF ),
LIT64( 0xFFFFFEFFFFFFFFFF ),
LIT64( 0xFFFFFDFFFFFFFFFF ),
LIT64( 0xFFFFFBFFFFFFFFFF ),
LIT64( 0xFFFFF7FFFFFFFFFF ),
LIT64( 0xFFFFEFFFFFFFFFFF ),
LIT64( 0xFFFFDFFFFFFFFFFF ),
LIT64( 0xFFFFBFFFFFFFFFFF ),
LIT64( 0xFFFF7FFFFFFFFFFF ),
LIT64( 0xFFFEFFFFFFFFFFFF ),
LIT64( 0xFFFDFFFFFFFFFFFF ),
LIT64( 0xFFFBFFFFFFFFFFFF ),
LIT64( 0xFFF7FFFFFFFFFFFF ),
LIT64( 0xFFEFFFFFFFFFFFFF ),
LIT64( 0xFFDFFFFFFFFFFFFF ),
LIT64( 0xFFBFFFFFFFFFFFFF ),
LIT64( 0xFF7FFFFFFFFFFFFF ),
LIT64( 0xFEFFFFFFFFFFFFFF ),
LIT64( 0xFDFFFFFFFFFFFFFF ),
LIT64( 0xFBFFFFFFFFFFFFFF ),
LIT64( 0xF7FFFFFFFFFFFFFF ),
LIT64( 0xEFFFFFFFFFFFFFFF ),
LIT64( 0xDFFFFFFFFFFFFFFF ),
LIT64( 0xBFFFFFFFFFFFFFFF ),
LIT64( 0x7FFFFFFFFFFFFFFF ),
LIT64( 0x3FFFFFFFFFFFFFFF ),
LIT64( 0x1FFFFFFFFFFFFFFF ),
LIT64( 0x0FFFFFFFFFFFFFFF ),
LIT64( 0x07FFFFFFFFFFFFFF ),
LIT64( 0x03FFFFFFFFFFFFFF ),
LIT64( 0x01FFFFFFFFFFFFFF ),
LIT64( 0x00FFFFFFFFFFFFFF ),
LIT64( 0x007FFFFFFFFFFFFF ),
LIT64( 0x003FFFFFFFFFFFFF ),
LIT64( 0x001FFFFFFFFFFFFF ),
LIT64( 0x000FFFFFFFFFFFFF ),
LIT64( 0x0007FFFFFFFFFFFF ),
LIT64( 0x0003FFFFFFFFFFFF ),
LIT64( 0x0001FFFFFFFFFFFF ),
LIT64( 0x0000FFFFFFFFFFFF ),
LIT64( 0x00007FFFFFFFFFFF ),
LIT64( 0x00003FFFFFFFFFFF ),
LIT64( 0x00001FFFFFFFFFFF ),
LIT64( 0x00000FFFFFFFFFFF ),
LIT64( 0x000007FFFFFFFFFF ),
LIT64( 0x000003FFFFFFFFFF ),
LIT64( 0x000001FFFFFFFFFF ),
LIT64( 0x000000FFFFFFFFFF ),
LIT64( 0x0000007FFFFFFFFF ),
LIT64( 0x0000003FFFFFFFFF ),
LIT64( 0x0000001FFFFFFFFF ),
LIT64( 0x0000000FFFFFFFFF ),
LIT64( 0x00000007FFFFFFFF ),
LIT64( 0x00000003FFFFFFFF ),
LIT64( 0x00000001FFFFFFFF ),
LIT64( 0x00000000FFFFFFFF ),
LIT64( 0x000000007FFFFFFF ),
LIT64( 0x000000003FFFFFFF ),
LIT64( 0x000000001FFFFFFF ),
LIT64( 0x000000000FFFFFFF ),
LIT64( 0x0000000007FFFFFF ),
LIT64( 0x0000000003FFFFFF ),
LIT64( 0x0000000001FFFFFF ),
LIT64( 0x0000000000FFFFFF ),
LIT64( 0x00000000007FFFFF ),
LIT64( 0x00000000003FFFFF ),
LIT64( 0x00000000001FFFFF ),
LIT64( 0x00000000000FFFFF ),
LIT64( 0x000000000007FFFF ),
LIT64( 0x000000000003FFFF ),
LIT64( 0x000000000001FFFF ),
LIT64( 0x000000000000FFFF ),
LIT64( 0x0000000000007FFF ),
LIT64( 0x0000000000003FFF ),
LIT64( 0x0000000000001FFF ),
LIT64( 0x0000000000000FFF ),
LIT64( 0x00000000000007FF ),
LIT64( 0x00000000000003FF ),
LIT64( 0x00000000000001FF ),
LIT64( 0x00000000000000FF ),
LIT64( 0x000000000000007F ),
LIT64( 0x000000000000003F ),
LIT64( 0x000000000000001F ),
LIT64( 0x000000000000000F ),
LIT64( 0x0000000000000007 ),
LIT64( 0x0000000000000003 )
};
 
static int64 int64NextP1( sequenceT *sequencePtr )
{
uint8 termNum;
int64 z;
 
termNum = sequencePtr->term1Num;
z = int64P1[ termNum ];
++termNum;
if ( int64NumP1 <= termNum ) {
termNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->term1Num = termNum;
return (sbits64) z;
 
}
 
static const int64 int64NumP2 = ( int64NumP1 * int64NumP1 + int64NumP1 ) / 2;
 
static int64 int64NextP2( sequenceT *sequencePtr )
{
uint8 term1Num, term2Num;
int64 z;
 
term2Num = sequencePtr->term2Num;
term1Num = sequencePtr->term1Num;
z = int64P1[ term1Num ] + int64P1[ term2Num ];
++term2Num;
if ( int64NumP1 <= term2Num ) {
++term1Num;
if ( int64NumP1 <= term1Num ) {
term1Num = 0;
sequencePtr->done = TRUE;
}
term2Num = term1Num;
sequencePtr->term1Num = term1Num;
}
sequencePtr->term2Num = term2Num;
return (sbits64) z;
 
}
 
static int64 int64RandomP3( void )
{
 
return
(sbits64) (
int64P1[ randomUint8() % int64NumP1 ]
+ int64P1[ randomUint8() % int64NumP1 ]
+ int64P1[ randomUint8() % int64NumP1 ]
);
 
}
 
enum {
int64NumPInfWeightMasks = 61
};
 
static const uint64 int64PInfWeightMasks[ int64NumPInfWeightMasks ] = {
LIT64( 0xFFFFFFFFFFFFFFFF ),
LIT64( 0x7FFFFFFFFFFFFFFF ),
LIT64( 0x3FFFFFFFFFFFFFFF ),
LIT64( 0x1FFFFFFFFFFFFFFF ),
LIT64( 0x0FFFFFFFFFFFFFFF ),
LIT64( 0x07FFFFFFFFFFFFFF ),
LIT64( 0x03FFFFFFFFFFFFFF ),
LIT64( 0x01FFFFFFFFFFFFFF ),
LIT64( 0x00FFFFFFFFFFFFFF ),
LIT64( 0x007FFFFFFFFFFFFF ),
LIT64( 0x003FFFFFFFFFFFFF ),
LIT64( 0x001FFFFFFFFFFFFF ),
LIT64( 0x000FFFFFFFFFFFFF ),
LIT64( 0x0007FFFFFFFFFFFF ),
LIT64( 0x0003FFFFFFFFFFFF ),
LIT64( 0x0001FFFFFFFFFFFF ),
LIT64( 0x0000FFFFFFFFFFFF ),
LIT64( 0x00007FFFFFFFFFFF ),
LIT64( 0x00003FFFFFFFFFFF ),
LIT64( 0x00001FFFFFFFFFFF ),
LIT64( 0x00000FFFFFFFFFFF ),
LIT64( 0x000007FFFFFFFFFF ),
LIT64( 0x000003FFFFFFFFFF ),
LIT64( 0x000001FFFFFFFFFF ),
LIT64( 0x000000FFFFFFFFFF ),
LIT64( 0x0000007FFFFFFFFF ),
LIT64( 0x0000003FFFFFFFFF ),
LIT64( 0x0000001FFFFFFFFF ),
LIT64( 0x0000000FFFFFFFFF ),
LIT64( 0x00000007FFFFFFFF ),
LIT64( 0x00000003FFFFFFFF ),
LIT64( 0x00000001FFFFFFFF ),
LIT64( 0x00000000FFFFFFFF ),
LIT64( 0x000000007FFFFFFF ),
LIT64( 0x000000003FFFFFFF ),
LIT64( 0x000000001FFFFFFF ),
LIT64( 0x000000000FFFFFFF ),
LIT64( 0x0000000007FFFFFF ),
LIT64( 0x0000000003FFFFFF ),
LIT64( 0x0000000001FFFFFF ),
LIT64( 0x0000000000FFFFFF ),
LIT64( 0x00000000007FFFFF ),
LIT64( 0x00000000003FFFFF ),
LIT64( 0x00000000001FFFFF ),
LIT64( 0x00000000000FFFFF ),
LIT64( 0x000000000007FFFF ),
LIT64( 0x000000000003FFFF ),
LIT64( 0x000000000001FFFF ),
LIT64( 0x000000000000FFFF ),
LIT64( 0x0000000000007FFF ),
LIT64( 0x0000000000003FFF ),
LIT64( 0x0000000000001FFF ),
LIT64( 0x0000000000000FFF ),
LIT64( 0x00000000000007FF ),
LIT64( 0x00000000000003FF ),
LIT64( 0x00000000000001FF ),
LIT64( 0x00000000000000FF ),
LIT64( 0x000000000000007F ),
LIT64( 0x000000000000003F ),
LIT64( 0x000000000000001F ),
LIT64( 0x000000000000000F )
};
 
static const uint64 int64PInfWeightOffsets[ int64NumPInfWeightMasks ] = {
LIT64( 0x0000000000000000 ),
LIT64( 0xC000000000000000 ),
LIT64( 0xE000000000000000 ),
LIT64( 0xF000000000000000 ),
LIT64( 0xF800000000000000 ),
LIT64( 0xFC00000000000000 ),
LIT64( 0xFE00000000000000 ),
LIT64( 0xFF00000000000000 ),
LIT64( 0xFF80000000000000 ),
LIT64( 0xFFC0000000000000 ),
LIT64( 0xFFE0000000000000 ),
LIT64( 0xFFF0000000000000 ),
LIT64( 0xFFF8000000000000 ),
LIT64( 0xFFFC000000000000 ),
LIT64( 0xFFFE000000000000 ),
LIT64( 0xFFFF000000000000 ),
LIT64( 0xFFFF800000000000 ),
LIT64( 0xFFFFC00000000000 ),
LIT64( 0xFFFFE00000000000 ),
LIT64( 0xFFFFF00000000000 ),
LIT64( 0xFFFFF80000000000 ),
LIT64( 0xFFFFFC0000000000 ),
LIT64( 0xFFFFFE0000000000 ),
LIT64( 0xFFFFFF0000000000 ),
LIT64( 0xFFFFFF8000000000 ),
LIT64( 0xFFFFFFC000000000 ),
LIT64( 0xFFFFFFE000000000 ),
LIT64( 0xFFFFFFF000000000 ),
LIT64( 0xFFFFFFF800000000 ),
LIT64( 0xFFFFFFFC00000000 ),
LIT64( 0xFFFFFFFE00000000 ),
LIT64( 0xFFFFFFFF00000000 ),
LIT64( 0xFFFFFFFF80000000 ),
LIT64( 0xFFFFFFFFC0000000 ),
LIT64( 0xFFFFFFFFE0000000 ),
LIT64( 0xFFFFFFFFF0000000 ),
LIT64( 0xFFFFFFFFF8000000 ),
LIT64( 0xFFFFFFFFFC000000 ),
LIT64( 0xFFFFFFFFFE000000 ),
LIT64( 0xFFFFFFFFFF000000 ),
LIT64( 0xFFFFFFFFFF800000 ),
LIT64( 0xFFFFFFFFFFC00000 ),
LIT64( 0xFFFFFFFFFFE00000 ),
LIT64( 0xFFFFFFFFFFF00000 ),
LIT64( 0xFFFFFFFFFFF80000 ),
LIT64( 0xFFFFFFFFFFFC0000 ),
LIT64( 0xFFFFFFFFFFFE0000 ),
LIT64( 0xFFFFFFFFFFFF0000 ),
LIT64( 0xFFFFFFFFFFFF8000 ),
LIT64( 0xFFFFFFFFFFFFC000 ),
LIT64( 0xFFFFFFFFFFFFE000 ),
LIT64( 0xFFFFFFFFFFFFF000 ),
LIT64( 0xFFFFFFFFFFFFF800 ),
LIT64( 0xFFFFFFFFFFFFFC00 ),
LIT64( 0xFFFFFFFFFFFFFE00 ),
LIT64( 0xFFFFFFFFFFFFFF00 ),
LIT64( 0xFFFFFFFFFFFFFF80 ),
LIT64( 0xFFFFFFFFFFFFFFC0 ),
LIT64( 0xFFFFFFFFFFFFFFE0 ),
LIT64( 0xFFFFFFFFFFFFFFF0 ),
LIT64( 0xFFFFFFFFFFFFFFF8 )
};
 
static int64 int64RandomPInf( void )
{
int8 weightMaskNum;
 
weightMaskNum = randomUint8() % int64NumPInfWeightMasks;
return
(sbits64) (
( randomUint64() & int64PInfWeightMasks[ weightMaskNum ] )
+ int64PInfWeightOffsets[ weightMaskNum ]
);
 
}
 
#endif
 
enum {
float32NumQIn = 22,
float32NumQOut = 50,
float32NumP1 = 4,
float32NumP2 = 88
};
 
static const uint32 float32QIn[ float32NumQIn ] = {
0x00000000, /* positive, subnormal */
0x00800000, /* positive, -126 */
0x33800000, /* positive, -24 */
0x3E800000, /* positive, -2 */
0x3F000000, /* positive, -1 */
0x3F800000, /* positive, 0 */
0x40000000, /* positive, 1 */
0x40800000, /* positive, 2 */
0x4B800000, /* positive, 24 */
0x7F000000, /* positive, 127 */
0x7F800000, /* positive, infinity or NaN */
0x80000000, /* negative, subnormal */
0x80800000, /* negative, -126 */
0xB3800000, /* negative, -24 */
0xBE800000, /* negative, -2 */
0xBF000000, /* negative, -1 */
0xBF800000, /* negative, 0 */
0xC0000000, /* negative, 1 */
0xC0800000, /* negative, 2 */
0xCB800000, /* negative, 24 */
0xFE800000, /* negative, 126 */
0xFF800000 /* negative, infinity or NaN */
};
 
static const uint32 float32QOut[ float32NumQOut ] = {
0x00000000, /* positive, subnormal */
0x00800000, /* positive, -126 */
0x01000000, /* positive, -125 */
0x33800000, /* positive, -24 */
0x3D800000, /* positive, -4 */
0x3E000000, /* positive, -3 */
0x3E800000, /* positive, -2 */
0x3F000000, /* positive, -1 */
0x3F800000, /* positive, 0 */
0x40000000, /* positive, 1 */
0x40800000, /* positive, 2 */
0x41000000, /* positive, 3 */
0x41800000, /* positive, 4 */
0x4B800000, /* positive, 24 */
0x4E000000, /* positive, 29 */
0x4E800000, /* positive, 30 */
0x4F000000, /* positive, 31 */
0x4F800000, /* positive, 32 */
0x5E000000, /* positive, 61 */
0x5E800000, /* positive, 62 */
0x5F000000, /* positive, 63 */
0x5F800000, /* positive, 64 */
0x7E800000, /* positive, 126 */
0x7F000000, /* positive, 127 */
0x7F800000, /* positive, infinity or NaN */
0x80000000, /* negative, subnormal */
0x80800000, /* negative, -126 */
0x81000000, /* negative, -125 */
0xB3800000, /* negative, -24 */
0xBD800000, /* negative, -4 */
0xBE000000, /* negative, -3 */
0xBE800000, /* negative, -2 */
0xBF000000, /* negative, -1 */
0xBF800000, /* negative, 0 */
0xC0000000, /* negative, 1 */
0xC0800000, /* negative, 2 */
0xC1000000, /* negative, 3 */
0xC1800000, /* negative, 4 */
0xCB800000, /* negative, 24 */
0xCE000000, /* negative, 29 */
0xCE800000, /* negative, 30 */
0xCF000000, /* negative, 31 */
0xCF800000, /* negative, 32 */
0xDE000000, /* negative, 61 */
0xDE800000, /* negative, 62 */
0xDF000000, /* negative, 63 */
0xDF800000, /* negative, 64 */
0xFE800000, /* negative, 126 */
0xFF000000, /* negative, 127 */
0xFF800000 /* negative, infinity or NaN */
};
 
static const uint32 float32P1[ float32NumP1 ] = {
0x00000000,
0x00000001,
0x007FFFFF,
0x007FFFFE
};
 
static const uint32 float32P2[ float32NumP2 ] = {
0x00000000,
0x00000001,
0x00000002,
0x00000004,
0x00000008,
0x00000010,
0x00000020,
0x00000040,
0x00000080,
0x00000100,
0x00000200,
0x00000400,
0x00000800,
0x00001000,
0x00002000,
0x00004000,
0x00008000,
0x00010000,
0x00020000,
0x00040000,
0x00080000,
0x00100000,
0x00200000,
0x00400000,
0x00600000,
0x00700000,
0x00780000,
0x007C0000,
0x007E0000,
0x007F0000,
0x007F8000,
0x007FC000,
0x007FE000,
0x007FF000,
0x007FF800,
0x007FFC00,
0x007FFE00,
0x007FFF00,
0x007FFF80,
0x007FFFC0,
0x007FFFE0,
0x007FFFF0,
0x007FFFF8,
0x007FFFFC,
0x007FFFFE,
0x007FFFFF,
0x007FFFFD,
0x007FFFFB,
0x007FFFF7,
0x007FFFEF,
0x007FFFDF,
0x007FFFBF,
0x007FFF7F,
0x007FFEFF,
0x007FFDFF,
0x007FFBFF,
0x007FF7FF,
0x007FEFFF,
0x007FDFFF,
0x007FBFFF,
0x007F7FFF,
0x007EFFFF,
0x007DFFFF,
0x007BFFFF,
0x0077FFFF,
0x006FFFFF,
0x005FFFFF,
0x003FFFFF,
0x001FFFFF,
0x000FFFFF,
0x0007FFFF,
0x0003FFFF,
0x0001FFFF,
0x0000FFFF,
0x00007FFF,
0x00003FFF,
0x00001FFF,
0x00000FFF,
0x000007FF,
0x000003FF,
0x000001FF,
0x000000FF,
0x0000007F,
0x0000003F,
0x0000001F,
0x0000000F,
0x00000007,
0x00000003
};
 
static const uint32 float32NumQInP1 = float32NumQIn * float32NumP1;
static const uint32 float32NumQOutP1 = float32NumQOut * float32NumP1;
 
static float32 float32NextQInP1( sequenceT *sequencePtr )
{
uint8 expNum, sigNum;
float32 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z = float32QIn[ expNum ] | float32P1[ sigNum ];
++sigNum;
if ( float32NumP1 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float32NumQIn <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static float32 float32NextQOutP1( sequenceT *sequencePtr )
{
uint8 expNum, sigNum;
float32 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z = float32QOut[ expNum ] | float32P1[ sigNum ];
++sigNum;
if ( float32NumP1 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float32NumQOut <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static const uint32 float32NumQInP2 = float32NumQIn * float32NumP2;
static const uint32 float32NumQOutP2 = float32NumQOut * float32NumP2;
 
static float32 float32NextQInP2( sequenceT *sequencePtr )
{
uint8 expNum, sigNum;
float32 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z = float32QIn[ expNum ] | float32P2[ sigNum ];
++sigNum;
if ( float32NumP2 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float32NumQIn <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static float32 float32NextQOutP2( sequenceT *sequencePtr )
{
uint8 expNum, sigNum;
float32 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z = float32QOut[ expNum ] | float32P2[ sigNum ];
++sigNum;
if ( float32NumP2 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float32NumQOut <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static float32 float32RandomQOutP3( void )
{
 
return
float32QOut[ randomUint8() % float32NumQOut ]
| ( ( float32P2[ randomUint8() % float32NumP2 ]
+ float32P2[ randomUint8() % float32NumP2 ] )
& 0x007FFFFF );
 
}
 
static float32 float32RandomQOutPInf( void )
{
 
return
float32QOut[ randomUint8() % float32NumQOut ]
| ( randomUint32() & 0x007FFFFF );
 
}
 
enum {
float32NumQInfWeightMasks = 7
};
 
static const uint32 float32QInfWeightMasks[ float32NumQInfWeightMasks ] = {
0x7F800000,
0x7F800000,
0x3F800000,
0x1F800000,
0x0F800000,
0x07800000,
0x03800000
};
 
static const uint32 float32QInfWeightOffsets[ float32NumQInfWeightMasks ] = {
0x00000000,
0x00000000,
0x20000000,
0x30000000,
0x38000000,
0x3C000000,
0x3E000000
};
 
static float32 float32RandomQInfP3( void )
{
int8 weightMaskNum;
 
weightMaskNum = randomUint8() % float32NumQInfWeightMasks;
return
( ( (uint32) ( randomUint8() & 1 ) )<<31 )
| ( ( ( ( (uint32) ( randomUint16() & 0x1FF ) )<<23 )
& float32QInfWeightMasks[ weightMaskNum ] )
+ float32QInfWeightOffsets[ weightMaskNum ]
)
| ( ( float32P2[ randomUint8() % float32NumP2 ]
+ float32P2[ randomUint8() % float32NumP2 ] )
& 0x007FFFFF );
 
}
 
static float32 float32RandomQInfPInf( void )
{
int8 weightMaskNum;
 
weightMaskNum = randomUint8() % float32NumQInfWeightMasks;
return
( ( (uint32) ( randomUint8() & 1 ) )<<31 )
| ( ( ( ( (uint32) ( randomUint16() & 0x1FF ) )<<23 )
& float32QInfWeightMasks[ weightMaskNum ] )
+ float32QInfWeightOffsets[ weightMaskNum ]
)
| ( randomUint32() & 0x007FFFFF );
 
}
 
static float32 float32Random( void )
{
 
switch ( randomUint8() & 7 ) {
case 0:
case 1:
case 2:
return float32RandomQOutP3();
case 3:
return float32RandomQOutPInf();
case 4:
case 5:
case 6:
return float32RandomQInfP3();
case 7:
return float32RandomQInfPInf();
default:
// Added this - GCC warning that control reached end of non-void return
// function, but we actually cover all cases here (0-7) for the 3-bit
// value that results from the masking in the switch() - JB
return 0;
}
 
}
 
#ifdef BITS64
#define SETFLOAT64( z, zHigh, zLow ) z = ( ( (float64) zHigh )<<32 ) | zLow
#else
#define SETFLOAT64( z, zHigh, zLow ) z.low = zLow; z.high = zHigh
#endif
 
enum {
float64NumQIn = 22,
float64NumQOut = 64,
float64NumP1 = 4,
float64NumP2 = 204
};
 
static const uint32 float64QIn[ float64NumQIn ] = {
0x00000000, /* positive, subnormal */
0x00100000, /* positive, -1022 */
0x3CA00000, /* positive, -53 */
0x3FD00000, /* positive, -2 */
0x3FE00000, /* positive, -1 */
0x3FF00000, /* positive, 0 */
0x40000000, /* positive, 1 */
0x40100000, /* positive, 2 */
0x43400000, /* positive, 53 */
0x7FE00000, /* positive, 1023 */
0x7FF00000, /* positive, infinity or NaN */
0x80000000, /* negative, subnormal */
0x80100000, /* negative, -1022 */
0xBCA00000, /* negative, -53 */
0xBFD00000, /* negative, -2 */
0xBFE00000, /* negative, -1 */
0xBFF00000, /* negative, 0 */
0xC0000000, /* negative, 1 */
0xC0100000, /* negative, 2 */
0xC3400000, /* negative, 53 */
0xFFE00000, /* negative, 1023 */
0xFFF00000 /* negative, infinity or NaN */
};
 
static const uint32 float64QOut[ float64NumQOut ] = {
0x00000000, /* positive, subnormal */
0x00100000, /* positive, -1022 */
0x00200000, /* positive, -1021 */
0x37E00000, /* positive, -129 */
0x37F00000, /* positive, -128 */
0x38000000, /* positive, -127 */
0x38100000, /* positive, -126 */
0x3CA00000, /* positive, -53 */
0x3FB00000, /* positive, -4 */
0x3FC00000, /* positive, -3 */
0x3FD00000, /* positive, -2 */
0x3FE00000, /* positive, -1 */
0x3FF00000, /* positive, 0 */
0x40000000, /* positive, 1 */
0x40100000, /* positive, 2 */
0x40200000, /* positive, 3 */
0x40300000, /* positive, 4 */
0x41C00000, /* positive, 29 */
0x41D00000, /* positive, 30 */
0x41E00000, /* positive, 31 */
0x41F00000, /* positive, 32 */
0x43400000, /* positive, 53 */
0x43C00000, /* positive, 61 */
0x43D00000, /* positive, 62 */
0x43E00000, /* positive, 63 */
0x43F00000, /* positive, 64 */
0x47E00000, /* positive, 127 */
0x47F00000, /* positive, 128 */
0x48000000, /* positive, 129 */
0x7FD00000, /* positive, 1022 */
0x7FE00000, /* positive, 1023 */
0x7FF00000, /* positive, infinity or NaN */
0x80000000, /* negative, subnormal */
0x80100000, /* negative, -1022 */
0x80200000, /* negative, -1021 */
0xB7E00000, /* negative, -129 */
0xB7F00000, /* negative, -128 */
0xB8000000, /* negative, -127 */
0xB8100000, /* negative, -126 */
0xBCA00000, /* negative, -53 */
0xBFB00000, /* negative, -4 */
0xBFC00000, /* negative, -3 */
0xBFD00000, /* negative, -2 */
0xBFE00000, /* negative, -1 */
0xBFF00000, /* negative, 0 */
0xC0000000, /* negative, 1 */
0xC0100000, /* negative, 2 */
0xC0200000, /* negative, 3 */
0xC0300000, /* negative, 4 */
0xC1C00000, /* negative, 29 */
0xC1D00000, /* negative, 30 */
0xC1E00000, /* negative, 31 */
0xC1F00000, /* negative, 32 */
0xC3400000, /* negative, 53 */
0xC3C00000, /* negative, 61 */
0xC3D00000, /* negative, 62 */
0xC3E00000, /* negative, 63 */
0xC3F00000, /* negative, 64 */
0xC7E00000, /* negative, 127 */
0xC7F00000, /* negative, 128 */
0xC8000000, /* negative, 129 */
0xFFD00000, /* negative, 1022 */
0xFFE00000, /* negative, 1023 */
0xFFF00000 /* negative, infinity or NaN */
};
 
static const struct { bits32 high, low; } float64P1[ float64NumP1 ] = {
{ 0x00000000, 0x00000000 },
{ 0x00000000, 0x00000001 },
{ 0x000FFFFF, 0xFFFFFFFF },
{ 0x000FFFFF, 0xFFFFFFFE }
};
 
static const struct { bits32 high, low; } float64P2[ float64NumP2 ] = {
{ 0x00000000, 0x00000000 },
{ 0x00000000, 0x00000001 },
{ 0x00000000, 0x00000002 },
{ 0x00000000, 0x00000004 },
{ 0x00000000, 0x00000008 },
{ 0x00000000, 0x00000010 },
{ 0x00000000, 0x00000020 },
{ 0x00000000, 0x00000040 },
{ 0x00000000, 0x00000080 },
{ 0x00000000, 0x00000100 },
{ 0x00000000, 0x00000200 },
{ 0x00000000, 0x00000400 },
{ 0x00000000, 0x00000800 },
{ 0x00000000, 0x00001000 },
{ 0x00000000, 0x00002000 },
{ 0x00000000, 0x00004000 },
{ 0x00000000, 0x00008000 },
{ 0x00000000, 0x00010000 },
{ 0x00000000, 0x00020000 },
{ 0x00000000, 0x00040000 },
{ 0x00000000, 0x00080000 },
{ 0x00000000, 0x00100000 },
{ 0x00000000, 0x00200000 },
{ 0x00000000, 0x00400000 },
{ 0x00000000, 0x00800000 },
{ 0x00000000, 0x01000000 },
{ 0x00000000, 0x02000000 },
{ 0x00000000, 0x04000000 },
{ 0x00000000, 0x08000000 },
{ 0x00000000, 0x10000000 },
{ 0x00000000, 0x20000000 },
{ 0x00000000, 0x40000000 },
{ 0x00000000, 0x80000000 },
{ 0x00000001, 0x00000000 },
{ 0x00000002, 0x00000000 },
{ 0x00000004, 0x00000000 },
{ 0x00000008, 0x00000000 },
{ 0x00000010, 0x00000000 },
{ 0x00000020, 0x00000000 },
{ 0x00000040, 0x00000000 },
{ 0x00000080, 0x00000000 },
{ 0x00000100, 0x00000000 },
{ 0x00000200, 0x00000000 },
{ 0x00000400, 0x00000000 },
{ 0x00000800, 0x00000000 },
{ 0x00001000, 0x00000000 },
{ 0x00002000, 0x00000000 },
{ 0x00004000, 0x00000000 },
{ 0x00008000, 0x00000000 },
{ 0x00010000, 0x00000000 },
{ 0x00020000, 0x00000000 },
{ 0x00040000, 0x00000000 },
{ 0x00080000, 0x00000000 },
{ 0x000C0000, 0x00000000 },
{ 0x000E0000, 0x00000000 },
{ 0x000F0000, 0x00000000 },
{ 0x000F8000, 0x00000000 },
{ 0x000FC000, 0x00000000 },
{ 0x000FE000, 0x00000000 },
{ 0x000FF000, 0x00000000 },
{ 0x000FF800, 0x00000000 },
{ 0x000FFC00, 0x00000000 },
{ 0x000FFE00, 0x00000000 },
{ 0x000FFF00, 0x00000000 },
{ 0x000FFF80, 0x00000000 },
{ 0x000FFFC0, 0x00000000 },
{ 0x000FFFE0, 0x00000000 },
{ 0x000FFFF0, 0x00000000 },
{ 0x000FFFF8, 0x00000000 },
{ 0x000FFFFC, 0x00000000 },
{ 0x000FFFFE, 0x00000000 },
{ 0x000FFFFF, 0x00000000 },
{ 0x000FFFFF, 0x80000000 },
{ 0x000FFFFF, 0xC0000000 },
{ 0x000FFFFF, 0xE0000000 },
{ 0x000FFFFF, 0xF0000000 },
{ 0x000FFFFF, 0xF8000000 },
{ 0x000FFFFF, 0xFC000000 },
{ 0x000FFFFF, 0xFE000000 },
{ 0x000FFFFF, 0xFF000000 },
{ 0x000FFFFF, 0xFF800000 },
{ 0x000FFFFF, 0xFFC00000 },
{ 0x000FFFFF, 0xFFE00000 },
{ 0x000FFFFF, 0xFFF00000 },
{ 0x000FFFFF, 0xFFF80000 },
{ 0x000FFFFF, 0xFFFC0000 },
{ 0x000FFFFF, 0xFFFE0000 },
{ 0x000FFFFF, 0xFFFF0000 },
{ 0x000FFFFF, 0xFFFF8000 },
{ 0x000FFFFF, 0xFFFFC000 },
{ 0x000FFFFF, 0xFFFFE000 },
{ 0x000FFFFF, 0xFFFFF000 },
{ 0x000FFFFF, 0xFFFFF800 },
{ 0x000FFFFF, 0xFFFFFC00 },
{ 0x000FFFFF, 0xFFFFFE00 },
{ 0x000FFFFF, 0xFFFFFF00 },
{ 0x000FFFFF, 0xFFFFFF80 },
{ 0x000FFFFF, 0xFFFFFFC0 },
{ 0x000FFFFF, 0xFFFFFFE0 },
{ 0x000FFFFF, 0xFFFFFFF0 },
{ 0x000FFFFF, 0xFFFFFFF8 },
{ 0x000FFFFF, 0xFFFFFFFC },
{ 0x000FFFFF, 0xFFFFFFFE },
{ 0x000FFFFF, 0xFFFFFFFF },
{ 0x000FFFFF, 0xFFFFFFFD },
{ 0x000FFFFF, 0xFFFFFFFB },
{ 0x000FFFFF, 0xFFFFFFF7 },
{ 0x000FFFFF, 0xFFFFFFEF },
{ 0x000FFFFF, 0xFFFFFFDF },
{ 0x000FFFFF, 0xFFFFFFBF },
{ 0x000FFFFF, 0xFFFFFF7F },
{ 0x000FFFFF, 0xFFFFFEFF },
{ 0x000FFFFF, 0xFFFFFDFF },
{ 0x000FFFFF, 0xFFFFFBFF },
{ 0x000FFFFF, 0xFFFFF7FF },
{ 0x000FFFFF, 0xFFFFEFFF },
{ 0x000FFFFF, 0xFFFFDFFF },
{ 0x000FFFFF, 0xFFFFBFFF },
{ 0x000FFFFF, 0xFFFF7FFF },
{ 0x000FFFFF, 0xFFFEFFFF },
{ 0x000FFFFF, 0xFFFDFFFF },
{ 0x000FFFFF, 0xFFFBFFFF },
{ 0x000FFFFF, 0xFFF7FFFF },
{ 0x000FFFFF, 0xFFEFFFFF },
{ 0x000FFFFF, 0xFFDFFFFF },
{ 0x000FFFFF, 0xFFBFFFFF },
{ 0x000FFFFF, 0xFF7FFFFF },
{ 0x000FFFFF, 0xFEFFFFFF },
{ 0x000FFFFF, 0xFDFFFFFF },
{ 0x000FFFFF, 0xFBFFFFFF },
{ 0x000FFFFF, 0xF7FFFFFF },
{ 0x000FFFFF, 0xEFFFFFFF },
{ 0x000FFFFF, 0xDFFFFFFF },
{ 0x000FFFFF, 0xBFFFFFFF },
{ 0x000FFFFF, 0x7FFFFFFF },
{ 0x000FFFFE, 0xFFFFFFFF },
{ 0x000FFFFD, 0xFFFFFFFF },
{ 0x000FFFFB, 0xFFFFFFFF },
{ 0x000FFFF7, 0xFFFFFFFF },
{ 0x000FFFEF, 0xFFFFFFFF },
{ 0x000FFFDF, 0xFFFFFFFF },
{ 0x000FFFBF, 0xFFFFFFFF },
{ 0x000FFF7F, 0xFFFFFFFF },
{ 0x000FFEFF, 0xFFFFFFFF },
{ 0x000FFDFF, 0xFFFFFFFF },
{ 0x000FFBFF, 0xFFFFFFFF },
{ 0x000FF7FF, 0xFFFFFFFF },
{ 0x000FEFFF, 0xFFFFFFFF },
{ 0x000FDFFF, 0xFFFFFFFF },
{ 0x000FBFFF, 0xFFFFFFFF },
{ 0x000F7FFF, 0xFFFFFFFF },
{ 0x000EFFFF, 0xFFFFFFFF },
{ 0x000DFFFF, 0xFFFFFFFF },
{ 0x000BFFFF, 0xFFFFFFFF },
{ 0x0007FFFF, 0xFFFFFFFF },
{ 0x0003FFFF, 0xFFFFFFFF },
{ 0x0001FFFF, 0xFFFFFFFF },
{ 0x0000FFFF, 0xFFFFFFFF },
{ 0x00007FFF, 0xFFFFFFFF },
{ 0x00003FFF, 0xFFFFFFFF },
{ 0x00001FFF, 0xFFFFFFFF },
{ 0x00000FFF, 0xFFFFFFFF },
{ 0x000007FF, 0xFFFFFFFF },
{ 0x000003FF, 0xFFFFFFFF },
{ 0x000001FF, 0xFFFFFFFF },
{ 0x000000FF, 0xFFFFFFFF },
{ 0x0000007F, 0xFFFFFFFF },
{ 0x0000003F, 0xFFFFFFFF },
{ 0x0000001F, 0xFFFFFFFF },
{ 0x0000000F, 0xFFFFFFFF },
{ 0x00000007, 0xFFFFFFFF },
{ 0x00000003, 0xFFFFFFFF },
{ 0x00000001, 0xFFFFFFFF },
{ 0x00000000, 0xFFFFFFFF },
{ 0x00000000, 0x7FFFFFFF },
{ 0x00000000, 0x3FFFFFFF },
{ 0x00000000, 0x1FFFFFFF },
{ 0x00000000, 0x0FFFFFFF },
{ 0x00000000, 0x07FFFFFF },
{ 0x00000000, 0x03FFFFFF },
{ 0x00000000, 0x01FFFFFF },
{ 0x00000000, 0x00FFFFFF },
{ 0x00000000, 0x007FFFFF },
{ 0x00000000, 0x003FFFFF },
{ 0x00000000, 0x001FFFFF },
{ 0x00000000, 0x000FFFFF },
{ 0x00000000, 0x0007FFFF },
{ 0x00000000, 0x0003FFFF },
{ 0x00000000, 0x0001FFFF },
{ 0x00000000, 0x0000FFFF },
{ 0x00000000, 0x00007FFF },
{ 0x00000000, 0x00003FFF },
{ 0x00000000, 0x00001FFF },
{ 0x00000000, 0x00000FFF },
{ 0x00000000, 0x000007FF },
{ 0x00000000, 0x000003FF },
{ 0x00000000, 0x000001FF },
{ 0x00000000, 0x000000FF },
{ 0x00000000, 0x0000007F },
{ 0x00000000, 0x0000003F },
{ 0x00000000, 0x0000001F },
{ 0x00000000, 0x0000000F },
{ 0x00000000, 0x00000007 },
{ 0x00000000, 0x00000003 }
};
 
static const uint32 float64NumQInP1 = float64NumQIn * float64NumP1;
static const uint32 float64NumQOutP1 = float64NumQOut * float64NumP1;
 
static float64 float64NextQInP1( sequenceT *sequencePtr )
{
uint8 expNum, sigNum;
float64 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
SETFLOAT64(
z,
float64QIn[ expNum ] | float64P1[ sigNum ].high,
float64P1[ sigNum ].low
);
++sigNum;
if ( float64NumP1 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float64NumQIn <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static float64 float64NextQOutP1( sequenceT *sequencePtr )
{
uint8 expNum, sigNum;
float64 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
SETFLOAT64(
z,
float64QOut[ expNum ] | float64P1[ sigNum ].high,
float64P1[ sigNum ].low
);
++sigNum;
if ( float64NumP1 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float64NumQOut <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static const uint32 float64NumQInP2 = float64NumQIn * float64NumP2;
static const uint32 float64NumQOutP2 = float64NumQOut * float64NumP2;
 
static float64 float64NextQInP2( sequenceT *sequencePtr )
{
uint8 expNum, sigNum;
float64 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
SETFLOAT64(
z,
float64QIn[ expNum ] | float64P2[ sigNum ].high,
float64P2[ sigNum ].low
);
++sigNum;
if ( float64NumP2 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float64NumQIn <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static float64 float64NextQOutP2( sequenceT *sequencePtr )
{
uint8 expNum, sigNum;
float64 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
SETFLOAT64(
z,
float64QOut[ expNum ] | float64P2[ sigNum ].high,
float64P2[ sigNum ].low
);
++sigNum;
if ( float64NumP2 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float64NumQOut <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static float64 float64RandomQOutP3( void )
{
int8 sigNum1, sigNum2;
uint32 sig1Low, sig2Low, zLow;
float64 z;
 
sigNum1 = randomUint8() % float64NumP2;
sigNum2 = randomUint8() % float64NumP2;
sig1Low = float64P2[ sigNum1 ].low;
sig2Low = float64P2[ sigNum2 ].low;
zLow = sig1Low + sig2Low;
SETFLOAT64(
z,
float64QOut[ randomUint8() % float64NumQOut ]
| ( ( float64P2[ sigNum1 ].high
+ float64P2[ sigNum2 ].high
+ ( zLow < sig1Low )
)
& 0x000FFFFF
),
zLow
);
return z;
 
}
 
static float64 float64RandomQOutPInf( void )
{
float64 z;
 
SETFLOAT64(
z,
float64QOut[ randomUint8() % float64NumQOut ]
| ( randomUint32() & 0x000FFFFF ),
randomUint32()
);
return z;
 
}
 
enum {
float64NumQInfWeightMasks = 10
};
 
static const uint32 float64QInfWeightMasks[ float64NumQInfWeightMasks ] = {
0x7FF00000,
0x7FF00000,
0x3FF00000,
0x1FF00000,
0x0FF00000,
0x07F00000,
0x03F00000,
0x01F00000,
0x00F00000,
0x00700000
};
 
static const uint32 float64QInfWeightOffsets[ float64NumQInfWeightMasks ] = {
0x00000000,
0x00000000,
0x20000000,
0x30000000,
0x38000000,
0x3C000000,
0x3E000000,
0x3F000000,
0x3F800000,
0x3FC00000
};
 
static float64 float64RandomQInfP3( void )
{
int8 sigNum1, sigNum2;
uint32 sig1Low, sig2Low, zLow;
int8 weightMaskNum;
float64 z;
 
sigNum1 = randomUint8() % float64NumP2;
sigNum2 = randomUint8() % float64NumP2;
sig1Low = float64P2[ sigNum1 ].low;
sig2Low = float64P2[ sigNum2 ].low;
zLow = sig1Low + sig2Low;
weightMaskNum = randomUint8() % float64NumQInfWeightMasks;
SETFLOAT64(
z,
( ( (uint32) ( randomUint8() & 1 ) )<<31 )
| ( ( ( ( (uint32) ( randomUint16() & 0xFFF ) )<<20 )
& float64QInfWeightMasks[ weightMaskNum ] )
+ float64QInfWeightOffsets[ weightMaskNum ]
)
| ( ( float64P2[ sigNum1 ].high
+ float64P2[ sigNum2 ].high
+ ( zLow < sig1Low )
)
& 0x000FFFFF
),
zLow
);
return z;
 
}
 
static float64 float64RandomQInfPInf( void )
{
int8 weightMaskNum;
float64 z;
 
weightMaskNum = randomUint8() % float64NumQInfWeightMasks;
SETFLOAT64(
z,
( ( (uint32) ( randomUint8() & 1 ) )<<31 )
| ( ( ( ( (uint32) ( randomUint16() & 0xFFF ) )<<20 )
& float64QInfWeightMasks[ weightMaskNum ] )
+ float64QInfWeightOffsets[ weightMaskNum ]
)
| ( randomUint32() & 0x000FFFFF ),
randomUint32()
);
return z;
 
}
 
static float64 float64Random( void )
{
 
switch ( randomUint8() & 7 ) {
case 0:
case 1:
case 2:
return float64RandomQOutP3();
case 3:
return float64RandomQOutPInf();
case 4:
case 5:
case 6:
return float64RandomQInfP3();
case 7:
return float64RandomQInfPInf();
default:
// Added this - GCC warning that control reached end of non-void return
// function, but we actually cover all cases here (0-7) for the 3-bit
// value that results from the masking in the switch() - JB
return 0;
}
 
}
 
#ifdef FLOATX80
 
enum {
floatx80NumQIn = 22,
floatx80NumQOut = 76,
floatx80NumP1 = 4,
floatx80NumP2 = 248
};
 
static const uint16 floatx80QIn[ floatx80NumQIn ] = {
0x0000, /* positive, subnormal */
0x0001, /* positive, -16382 */
0x3FBF, /* positive, -64 */
0x3FFD, /* positive, -2 */
0x3FFE, /* positive, -1 */
0x3FFF, /* positive, 0 */
0x4000, /* positive, 1 */
0x4001, /* positive, 2 */
0x403F, /* positive, 64 */
0x7FFE, /* positive, 16383 */
0x7FFF, /* positive, infinity or NaN */
0x8000, /* negative, subnormal */
0x8001, /* negative, -16382 */
0xBFBF, /* negative, -64 */
0xBFFD, /* negative, -2 */
0xBFFE, /* negative, -1 */
0xBFFF, /* negative, 0 */
0xC000, /* negative, 1 */
0xC001, /* negative, 2 */
0xC03F, /* negative, 64 */
0xFFFE, /* negative, 16383 */
0xFFFF /* negative, infinity or NaN */
};
 
static const uint16 floatx80QOut[ floatx80NumQOut ] = {
0x0000, /* positive, subnormal */
0x0001, /* positive, -16382 */
0x0002, /* positive, -16381 */
0x3BFE, /* positive, -1025 */
0x3BFF, /* positive, -1024 */
0x3C00, /* positive, -1023 */
0x3C01, /* positive, -1022 */
0x3F7E, /* positive, -129 */
0x3F7F, /* positive, -128 */
0x3F80, /* positive, -127 */
0x3F81, /* positive, -126 */
0x3FBF, /* positive, -64 */
0x3FFB, /* positive, -4 */
0x3FFC, /* positive, -3 */
0x3FFD, /* positive, -2 */
0x3FFE, /* positive, -1 */
0x3FFF, /* positive, 0 */
0x4000, /* positive, 1 */
0x4001, /* positive, 2 */
0x4002, /* positive, 3 */
0x4003, /* positive, 4 */
0x401C, /* positive, 29 */
0x401D, /* positive, 30 */
0x401E, /* positive, 31 */
0x401F, /* positive, 32 */
0x403C, /* positive, 61 */
0x403D, /* positive, 62 */
0x403E, /* positive, 63 */
0x403F, /* positive, 64 */
0x407E, /* positive, 127 */
0x407F, /* positive, 128 */
0x4080, /* positive, 129 */
0x43FE, /* positive, 1023 */
0x43FF, /* positive, 1024 */
0x4400, /* positive, 1025 */
0x7FFD, /* positive, 16382 */
0x7FFE, /* positive, 16383 */
0x7FFF, /* positive, infinity or NaN */
0x8000, /* negative, subnormal */
0x8001, /* negative, -16382 */
0x8002, /* negative, -16381 */
0xBBFE, /* negative, -1025 */
0xBBFF, /* negative, -1024 */
0xBC00, /* negative, -1023 */
0xBC01, /* negative, -1022 */
0xBF7E, /* negative, -129 */
0xBF7F, /* negative, -128 */
0xBF80, /* negative, -127 */
0xBF81, /* negative, -126 */
0xBFBF, /* negative, -64 */
0xBFFB, /* negative, -4 */
0xBFFC, /* negative, -3 */
0xBFFD, /* negative, -2 */
0xBFFE, /* negative, -1 */
0xBFFF, /* negative, 0 */
0xC000, /* negative, 1 */
0xC001, /* negative, 2 */
0xC002, /* negative, 3 */
0xC003, /* negative, 4 */
0xC01C, /* negative, 29 */
0xC01D, /* negative, 30 */
0xC01E, /* negative, 31 */
0xC01F, /* negative, 32 */
0xC03C, /* negative, 61 */
0xC03D, /* negative, 62 */
0xC03E, /* negative, 63 */
0xC03F, /* negative, 64 */
0xC07E, /* negative, 127 */
0xC07F, /* negative, 128 */
0xC080, /* negative, 129 */
0xC3FE, /* negative, 1023 */
0xC3FF, /* negative, 1024 */
0xC400, /* negative, 1025 */
0xFFFD, /* negative, 16382 */
0xFFFE, /* negative, 16383 */
0xFFFF /* negative, infinity or NaN */
};
 
static const bits64 floatx80P1[ floatx80NumP1 ] = {
LIT64( 0x0000000000000000 ),
LIT64( 0x0000000000000001 ),
LIT64( 0x7FFFFFFFFFFFFFFF ),
LIT64( 0x7FFFFFFFFFFFFFFE )
};
 
static const bits64 floatx80P2[ floatx80NumP2 ] = {
LIT64( 0x0000000000000000 ),
LIT64( 0x0000000000000001 ),
LIT64( 0x0000000000000002 ),
LIT64( 0x0000000000000004 ),
LIT64( 0x0000000000000008 ),
LIT64( 0x0000000000000010 ),
LIT64( 0x0000000000000020 ),
LIT64( 0x0000000000000040 ),
LIT64( 0x0000000000000080 ),
LIT64( 0x0000000000000100 ),
LIT64( 0x0000000000000200 ),
LIT64( 0x0000000000000400 ),
LIT64( 0x0000000000000800 ),
LIT64( 0x0000000000001000 ),
LIT64( 0x0000000000002000 ),
LIT64( 0x0000000000004000 ),
LIT64( 0x0000000000008000 ),
LIT64( 0x0000000000010000 ),
LIT64( 0x0000000000020000 ),
LIT64( 0x0000000000040000 ),
LIT64( 0x0000000000080000 ),
LIT64( 0x0000000000100000 ),
LIT64( 0x0000000000200000 ),
LIT64( 0x0000000000400000 ),
LIT64( 0x0000000000800000 ),
LIT64( 0x0000000001000000 ),
LIT64( 0x0000000002000000 ),
LIT64( 0x0000000004000000 ),
LIT64( 0x0000000008000000 ),
LIT64( 0x0000000010000000 ),
LIT64( 0x0000000020000000 ),
LIT64( 0x0000000040000000 ),
LIT64( 0x0000000080000000 ),
LIT64( 0x0000000100000000 ),
LIT64( 0x0000000200000000 ),
LIT64( 0x0000000400000000 ),
LIT64( 0x0000000800000000 ),
LIT64( 0x0000001000000000 ),
LIT64( 0x0000002000000000 ),
LIT64( 0x0000004000000000 ),
LIT64( 0x0000008000000000 ),
LIT64( 0x0000010000000000 ),
LIT64( 0x0000020000000000 ),
LIT64( 0x0000040000000000 ),
LIT64( 0x0000080000000000 ),
LIT64( 0x0000100000000000 ),
LIT64( 0x0000200000000000 ),
LIT64( 0x0000400000000000 ),
LIT64( 0x0000800000000000 ),
LIT64( 0x0001000000000000 ),
LIT64( 0x0002000000000000 ),
LIT64( 0x0004000000000000 ),
LIT64( 0x0008000000000000 ),
LIT64( 0x0010000000000000 ),
LIT64( 0x0020000000000000 ),
LIT64( 0x0040000000000000 ),
LIT64( 0x0080000000000000 ),
LIT64( 0x0100000000000000 ),
LIT64( 0x0200000000000000 ),
LIT64( 0x0400000000000000 ),
LIT64( 0x0800000000000000 ),
LIT64( 0x1000000000000000 ),
LIT64( 0x2000000000000000 ),
LIT64( 0x4000000000000000 ),
LIT64( 0x6000000000000000 ),
LIT64( 0x7000000000000000 ),
LIT64( 0x7800000000000000 ),
LIT64( 0x7C00000000000000 ),
LIT64( 0x7E00000000000000 ),
LIT64( 0x7F00000000000000 ),
LIT64( 0x7F80000000000000 ),
LIT64( 0x7FC0000000000000 ),
LIT64( 0x7FE0000000000000 ),
LIT64( 0x7FF0000000000000 ),
LIT64( 0x7FF8000000000000 ),
LIT64( 0x7FFC000000000000 ),
LIT64( 0x7FFE000000000000 ),
LIT64( 0x7FFF000000000000 ),
LIT64( 0x7FFF800000000000 ),
LIT64( 0x7FFFC00000000000 ),
LIT64( 0x7FFFE00000000000 ),
LIT64( 0x7FFFF00000000000 ),
LIT64( 0x7FFFF80000000000 ),
LIT64( 0x7FFFFC0000000000 ),
LIT64( 0x7FFFFE0000000000 ),
LIT64( 0x7FFFFF0000000000 ),
LIT64( 0x7FFFFF8000000000 ),
LIT64( 0x7FFFFFC000000000 ),
LIT64( 0x7FFFFFE000000000 ),
LIT64( 0x7FFFFFF000000000 ),
LIT64( 0x7FFFFFF800000000 ),
LIT64( 0x7FFFFFFC00000000 ),
LIT64( 0x7FFFFFFE00000000 ),
LIT64( 0x7FFFFFFF00000000 ),
LIT64( 0x7FFFFFFF80000000 ),
LIT64( 0x7FFFFFFFC0000000 ),
LIT64( 0x7FFFFFFFE0000000 ),
LIT64( 0x7FFFFFFFF0000000 ),
LIT64( 0x7FFFFFFFF8000000 ),
LIT64( 0x7FFFFFFFFC000000 ),
LIT64( 0x7FFFFFFFFE000000 ),
LIT64( 0x7FFFFFFFFF000000 ),
LIT64( 0x7FFFFFFFFF800000 ),
LIT64( 0x7FFFFFFFFFC00000 ),
LIT64( 0x7FFFFFFFFFE00000 ),
LIT64( 0x7FFFFFFFFFF00000 ),
LIT64( 0x7FFFFFFFFFF80000 ),
LIT64( 0x7FFFFFFFFFFC0000 ),
LIT64( 0x7FFFFFFFFFFE0000 ),
LIT64( 0x7FFFFFFFFFFF0000 ),
LIT64( 0x7FFFFFFFFFFF8000 ),
LIT64( 0x7FFFFFFFFFFFC000 ),
LIT64( 0x7FFFFFFFFFFFE000 ),
LIT64( 0x7FFFFFFFFFFFF000 ),
LIT64( 0x7FFFFFFFFFFFF800 ),
LIT64( 0x7FFFFFFFFFFFFC00 ),
LIT64( 0x7FFFFFFFFFFFFE00 ),
LIT64( 0x7FFFFFFFFFFFFF00 ),
LIT64( 0x7FFFFFFFFFFFFF80 ),
LIT64( 0x7FFFFFFFFFFFFFC0 ),
LIT64( 0x7FFFFFFFFFFFFFE0 ),
LIT64( 0x7FFFFFFFFFFFFFF0 ),
LIT64( 0x7FFFFFFFFFFFFFF8 ),
LIT64( 0x7FFFFFFFFFFFFFFC ),
LIT64( 0x7FFFFFFFFFFFFFFE ),
LIT64( 0x7FFFFFFFFFFFFFFF ),
LIT64( 0x7FFFFFFFFFFFFFFD ),
LIT64( 0x7FFFFFFFFFFFFFFB ),
LIT64( 0x7FFFFFFFFFFFFFF7 ),
LIT64( 0x7FFFFFFFFFFFFFEF ),
LIT64( 0x7FFFFFFFFFFFFFDF ),
LIT64( 0x7FFFFFFFFFFFFFBF ),
LIT64( 0x7FFFFFFFFFFFFF7F ),
LIT64( 0x7FFFFFFFFFFFFEFF ),
LIT64( 0x7FFFFFFFFFFFFDFF ),
LIT64( 0x7FFFFFFFFFFFFBFF ),
LIT64( 0x7FFFFFFFFFFFF7FF ),
LIT64( 0x7FFFFFFFFFFFEFFF ),
LIT64( 0x7FFFFFFFFFFFDFFF ),
LIT64( 0x7FFFFFFFFFFFBFFF ),
LIT64( 0x7FFFFFFFFFFF7FFF ),
LIT64( 0x7FFFFFFFFFFEFFFF ),
LIT64( 0x7FFFFFFFFFFDFFFF ),
LIT64( 0x7FFFFFFFFFFBFFFF ),
LIT64( 0x7FFFFFFFFFF7FFFF ),
LIT64( 0x7FFFFFFFFFEFFFFF ),
LIT64( 0x7FFFFFFFFFDFFFFF ),
LIT64( 0x7FFFFFFFFFBFFFFF ),
LIT64( 0x7FFFFFFFFF7FFFFF ),
LIT64( 0x7FFFFFFFFEFFFFFF ),
LIT64( 0x7FFFFFFFFDFFFFFF ),
LIT64( 0x7FFFFFFFFBFFFFFF ),
LIT64( 0x7FFFFFFFF7FFFFFF ),
LIT64( 0x7FFFFFFFEFFFFFFF ),
LIT64( 0x7FFFFFFFDFFFFFFF ),
LIT64( 0x7FFFFFFFBFFFFFFF ),
LIT64( 0x7FFFFFFF7FFFFFFF ),
LIT64( 0x7FFFFFFEFFFFFFFF ),
LIT64( 0x7FFFFFFDFFFFFFFF ),
LIT64( 0x7FFFFFFBFFFFFFFF ),
LIT64( 0x7FFFFFF7FFFFFFFF ),
LIT64( 0x7FFFFFEFFFFFFFFF ),
LIT64( 0x7FFFFFDFFFFFFFFF ),
LIT64( 0x7FFFFFBFFFFFFFFF ),
LIT64( 0x7FFFFF7FFFFFFFFF ),
LIT64( 0x7FFFFEFFFFFFFFFF ),
LIT64( 0x7FFFFDFFFFFFFFFF ),
LIT64( 0x7FFFFBFFFFFFFFFF ),
LIT64( 0x7FFFF7FFFFFFFFFF ),
LIT64( 0x7FFFEFFFFFFFFFFF ),
LIT64( 0x7FFFDFFFFFFFFFFF ),
LIT64( 0x7FFFBFFFFFFFFFFF ),
LIT64( 0x7FFF7FFFFFFFFFFF ),
LIT64( 0x7FFEFFFFFFFFFFFF ),
LIT64( 0x7FFDFFFFFFFFFFFF ),
LIT64( 0x7FFBFFFFFFFFFFFF ),
LIT64( 0x7FF7FFFFFFFFFFFF ),
LIT64( 0x7FEFFFFFFFFFFFFF ),
LIT64( 0x7FDFFFFFFFFFFFFF ),
LIT64( 0x7FBFFFFFFFFFFFFF ),
LIT64( 0x7F7FFFFFFFFFFFFF ),
LIT64( 0x7EFFFFFFFFFFFFFF ),
LIT64( 0x7DFFFFFFFFFFFFFF ),
LIT64( 0x7BFFFFFFFFFFFFFF ),
LIT64( 0x77FFFFFFFFFFFFFF ),
LIT64( 0x6FFFFFFFFFFFFFFF ),
LIT64( 0x5FFFFFFFFFFFFFFF ),
LIT64( 0x3FFFFFFFFFFFFFFF ),
LIT64( 0x1FFFFFFFFFFFFFFF ),
LIT64( 0x0FFFFFFFFFFFFFFF ),
LIT64( 0x07FFFFFFFFFFFFFF ),
LIT64( 0x03FFFFFFFFFFFFFF ),
LIT64( 0x01FFFFFFFFFFFFFF ),
LIT64( 0x00FFFFFFFFFFFFFF ),
LIT64( 0x007FFFFFFFFFFFFF ),
LIT64( 0x003FFFFFFFFFFFFF ),
LIT64( 0x001FFFFFFFFFFFFF ),
LIT64( 0x000FFFFFFFFFFFFF ),
LIT64( 0x0007FFFFFFFFFFFF ),
LIT64( 0x0003FFFFFFFFFFFF ),
LIT64( 0x0001FFFFFFFFFFFF ),
LIT64( 0x0000FFFFFFFFFFFF ),
LIT64( 0x00007FFFFFFFFFFF ),
LIT64( 0x00003FFFFFFFFFFF ),
LIT64( 0x00001FFFFFFFFFFF ),
LIT64( 0x00000FFFFFFFFFFF ),
LIT64( 0x000007FFFFFFFFFF ),
LIT64( 0x000003FFFFFFFFFF ),
LIT64( 0x000001FFFFFFFFFF ),
LIT64( 0x000000FFFFFFFFFF ),
LIT64( 0x0000007FFFFFFFFF ),
LIT64( 0x0000003FFFFFFFFF ),
LIT64( 0x0000001FFFFFFFFF ),
LIT64( 0x0000000FFFFFFFFF ),
LIT64( 0x00000007FFFFFFFF ),
LIT64( 0x00000003FFFFFFFF ),
LIT64( 0x00000001FFFFFFFF ),
LIT64( 0x00000000FFFFFFFF ),
LIT64( 0x000000007FFFFFFF ),
LIT64( 0x000000003FFFFFFF ),
LIT64( 0x000000001FFFFFFF ),
LIT64( 0x000000000FFFFFFF ),
LIT64( 0x0000000007FFFFFF ),
LIT64( 0x0000000003FFFFFF ),
LIT64( 0x0000000001FFFFFF ),
LIT64( 0x0000000000FFFFFF ),
LIT64( 0x00000000007FFFFF ),
LIT64( 0x00000000003FFFFF ),
LIT64( 0x00000000001FFFFF ),
LIT64( 0x00000000000FFFFF ),
LIT64( 0x000000000007FFFF ),
LIT64( 0x000000000003FFFF ),
LIT64( 0x000000000001FFFF ),
LIT64( 0x000000000000FFFF ),
LIT64( 0x0000000000007FFF ),
LIT64( 0x0000000000003FFF ),
LIT64( 0x0000000000001FFF ),
LIT64( 0x0000000000000FFF ),
LIT64( 0x00000000000007FF ),
LIT64( 0x00000000000003FF ),
LIT64( 0x00000000000001FF ),
LIT64( 0x00000000000000FF ),
LIT64( 0x000000000000007F ),
LIT64( 0x000000000000003F ),
LIT64( 0x000000000000001F ),
LIT64( 0x000000000000000F ),
LIT64( 0x0000000000000007 ),
LIT64( 0x0000000000000003 )
};
 
static const uint32 floatx80NumQInP1 = floatx80NumQIn * floatx80NumP1;
static const uint32 floatx80NumQOutP1 = floatx80NumQOut * floatx80NumP1;
 
static floatx80 floatx80NextQInP1( sequenceT *sequencePtr )
{
int16 expNum, sigNum;
floatx80 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z.low = floatx80P1[ sigNum ];
z.high = floatx80QIn[ expNum ];
if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
++sigNum;
if ( floatx80NumP1 <= sigNum ) {
sigNum = 0;
++expNum;
if ( floatx80NumQIn <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static floatx80 floatx80NextQOutP1( sequenceT *sequencePtr )
{
int16 expNum, sigNum;
floatx80 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z.low = floatx80P1[ sigNum ];
z.high = floatx80QOut[ expNum ];
if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
++sigNum;
if ( floatx80NumP1 <= sigNum ) {
sigNum = 0;
++expNum;
if ( floatx80NumQOut <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static const uint32 floatx80NumQInP2 = floatx80NumQIn * floatx80NumP2;
static const uint32 floatx80NumQOutP2 = floatx80NumQOut * floatx80NumP2;
 
static floatx80 floatx80NextQInP2( sequenceT *sequencePtr )
{
int16 expNum, sigNum;
floatx80 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z.low = floatx80P2[ sigNum ];
z.high = floatx80QIn[ expNum ];
if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
++sigNum;
if ( floatx80NumP2 <= sigNum ) {
sigNum = 0;
++expNum;
if ( floatx80NumQIn <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static floatx80 floatx80NextQOutP2( sequenceT *sequencePtr )
{
int16 expNum, sigNum;
floatx80 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z.low = floatx80P2[ sigNum ];
z.high = floatx80QOut[ expNum ];
if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
++sigNum;
if ( floatx80NumP2 <= sigNum ) {
sigNum = 0;
++expNum;
if ( floatx80NumQOut <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static floatx80 floatx80RandomQOutP3( void )
{
floatx80 z;
 
z.low =
( floatx80P2[ randomUint8() % floatx80NumP2 ]
+ floatx80P2[ randomUint8() % floatx80NumP2 ] )
& LIT64( 0x7FFFFFFFFFFFFFFF );
z.high = floatx80QOut[ randomUint8() % floatx80NumQOut ];
if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
return z;
 
}
 
static floatx80 floatx80RandomQOutPInf( void )
{
floatx80 z;
 
z.low = randomUint64() & LIT64( 0x7FFFFFFFFFFFFFFF );
z.high = floatx80QOut[ randomUint8() % floatx80NumQOut ];
if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
return z;
 
}
 
enum {
floatx80NumQInfWeightMasks = 14
};
 
static const uint16 floatx80QInfWeightMasks[ floatx80NumQInfWeightMasks ] = {
0x7FFF,
0x7FFF,
0x3FFF,
0x1FFF,
0x07FF,
0x07FF,
0x03FF,
0x01FF,
0x00FF,
0x007F,
0x003F,
0x001F,
0x000F,
0x0007
};
 
static const uint16 floatx80QInfWeightOffsets[ floatx80NumQInfWeightMasks ] = {
0x0000,
0x0000,
0x2000,
0x3000,
0x3800,
0x3C00,
0x3E00,
0x3F00,
0x3F80,
0x3FC0,
0x3FE0,
0x3FF0,
0x3FF8,
0x3FFC
};
 
static floatx80 floatx80RandomQInfP3( void )
{
int8 weightMaskNum;
floatx80 z;
 
z.low =
( floatx80P2[ randomUint8() % floatx80NumP2 ]
+ floatx80P2[ randomUint8() % floatx80NumP2 ] )
& LIT64( 0x7FFFFFFFFFFFFFFF );
weightMaskNum = randomUint8() % floatx80NumQInfWeightMasks;
z.high =
randomUint16() & floatx80QInfWeightMasks[ weightMaskNum ]
+ floatx80QInfWeightOffsets[ weightMaskNum ];
if ( z.high ) z.low |= LIT64( 0x8000000000000000 );
z.high |= ( (uint16) ( randomUint8() & 1 ) )<<15;
return z;
 
}
 
static floatx80 floatx80RandomQInfPInf( void )
{
int8 weightMaskNum;
floatx80 z;
 
z.low = randomUint64() & LIT64( 0x7FFFFFFFFFFFFFFF );
weightMaskNum = randomUint8() % floatx80NumQInfWeightMasks;
z.high =
randomUint16() & floatx80QInfWeightMasks[ weightMaskNum ]
+ floatx80QInfWeightOffsets[ weightMaskNum ];
if ( z.high ) z.low |= LIT64( 0x8000000000000000 );
z.high |= ( (uint16) ( randomUint8() & 1 ) )<<15;
return z;
 
}
 
static floatx80 floatx80Random( void )
{
 
switch ( randomUint8() & 7 ) {
case 0:
case 1:
case 2:
return floatx80RandomQOutP3();
case 3:
return floatx80RandomQOutPInf();
case 4:
case 5:
case 6:
return floatx80RandomQInfP3();
case 7:
return floatx80RandomQInfPInf();
}
 
}
 
#endif
 
#ifdef FLOAT128
 
enum {
float128NumQIn = 22,
float128NumQOut = 78,
float128NumP1 = 4,
float128NumP2 = 443
};
 
static const uint64 float128QIn[ float128NumQIn ] = {
LIT64( 0x0000000000000000 ), /* positive, subnormal */
LIT64( 0x0001000000000000 ), /* positive, -16382 */
LIT64( 0x3F8E000000000000 ), /* positive, -113 */
LIT64( 0x3FFD000000000000 ), /* positive, -2 */
LIT64( 0x3FFE000000000000 ), /* positive, -1 */
LIT64( 0x3FFF000000000000 ), /* positive, 0 */
LIT64( 0x4000000000000000 ), /* positive, 1 */
LIT64( 0x4001000000000000 ), /* positive, 2 */
LIT64( 0x4070000000000000 ), /* positive, 113 */
LIT64( 0x7FFE000000000000 ), /* positive, 16383 */
LIT64( 0x7FFF000000000000 ), /* positive, infinity or NaN */
LIT64( 0x8000000000000000 ), /* negative, subnormal */
LIT64( 0x8001000000000000 ), /* negative, -16382 */
LIT64( 0xBF8E000000000000 ), /* negative, -113 */
LIT64( 0xBFFD000000000000 ), /* negative, -2 */
LIT64( 0xBFFE000000000000 ), /* negative, -1 */
LIT64( 0xBFFF000000000000 ), /* negative, 0 */
LIT64( 0xC000000000000000 ), /* negative, 1 */
LIT64( 0xC001000000000000 ), /* negative, 2 */
LIT64( 0xC070000000000000 ), /* negative, 113 */
LIT64( 0xFFFE000000000000 ), /* negative, 16383 */
LIT64( 0xFFFF000000000000 ) /* negative, infinity or NaN */
};
 
static const uint64 float128QOut[ float128NumQOut ] = {
LIT64( 0x0000000000000000 ), /* positive, subnormal */
LIT64( 0x0001000000000000 ), /* positive, -16382 */
LIT64( 0x0002000000000000 ), /* positive, -16381 */
LIT64( 0x3BFE000000000000 ), /* positive, -1025 */
LIT64( 0x3BFF000000000000 ), /* positive, -1024 */
LIT64( 0x3C00000000000000 ), /* positive, -1023 */
LIT64( 0x3C01000000000000 ), /* positive, -1022 */
LIT64( 0x3F7E000000000000 ), /* positive, -129 */
LIT64( 0x3F7F000000000000 ), /* positive, -128 */
LIT64( 0x3F80000000000000 ), /* positive, -127 */
LIT64( 0x3F81000000000000 ), /* positive, -126 */
LIT64( 0x3F8E000000000000 ), /* positive, -113 */
LIT64( 0x3FFB000000000000 ), /* positive, -4 */
LIT64( 0x3FFC000000000000 ), /* positive, -3 */
LIT64( 0x3FFD000000000000 ), /* positive, -2 */
LIT64( 0x3FFE000000000000 ), /* positive, -1 */
LIT64( 0x3FFF000000000000 ), /* positive, 0 */
LIT64( 0x4000000000000000 ), /* positive, 1 */
LIT64( 0x4001000000000000 ), /* positive, 2 */
LIT64( 0x4002000000000000 ), /* positive, 3 */
LIT64( 0x4003000000000000 ), /* positive, 4 */
LIT64( 0x401C000000000000 ), /* positive, 29 */
LIT64( 0x401D000000000000 ), /* positive, 30 */
LIT64( 0x401E000000000000 ), /* positive, 31 */
LIT64( 0x401F000000000000 ), /* positive, 32 */
LIT64( 0x403C000000000000 ), /* positive, 61 */
LIT64( 0x403D000000000000 ), /* positive, 62 */
LIT64( 0x403E000000000000 ), /* positive, 63 */
LIT64( 0x403F000000000000 ), /* positive, 64 */
LIT64( 0x4070000000000000 ), /* positive, 113 */
LIT64( 0x407E000000000000 ), /* positive, 127 */
LIT64( 0x407F000000000000 ), /* positive, 128 */
LIT64( 0x4080000000000000 ), /* positive, 129 */
LIT64( 0x43FE000000000000 ), /* positive, 1023 */
LIT64( 0x43FF000000000000 ), /* positive, 1024 */
LIT64( 0x4400000000000000 ), /* positive, 1025 */
LIT64( 0x7FFD000000000000 ), /* positive, 16382 */
LIT64( 0x7FFE000000000000 ), /* positive, 16383 */
LIT64( 0x7FFF000000000000 ), /* positive, infinity or NaN */
LIT64( 0x8000000000000000 ), /* negative, subnormal */
LIT64( 0x8001000000000000 ), /* negative, -16382 */
LIT64( 0x8002000000000000 ), /* negative, -16381 */
LIT64( 0xBBFE000000000000 ), /* negative, -1025 */
LIT64( 0xBBFF000000000000 ), /* negative, -1024 */
LIT64( 0xBC00000000000000 ), /* negative, -1023 */
LIT64( 0xBC01000000000000 ), /* negative, -1022 */
LIT64( 0xBF7E000000000000 ), /* negative, -129 */
LIT64( 0xBF7F000000000000 ), /* negative, -128 */
LIT64( 0xBF80000000000000 ), /* negative, -127 */
LIT64( 0xBF81000000000000 ), /* negative, -126 */
LIT64( 0xBF8E000000000000 ), /* negative, -113 */
LIT64( 0xBFFB000000000000 ), /* negative, -4 */
LIT64( 0xBFFC000000000000 ), /* negative, -3 */
LIT64( 0xBFFD000000000000 ), /* negative, -2 */
LIT64( 0xBFFE000000000000 ), /* negative, -1 */
LIT64( 0xBFFF000000000000 ), /* negative, 0 */
LIT64( 0xC000000000000000 ), /* negative, 1 */
LIT64( 0xC001000000000000 ), /* negative, 2 */
LIT64( 0xC002000000000000 ), /* negative, 3 */
LIT64( 0xC003000000000000 ), /* negative, 4 */
LIT64( 0xC01C000000000000 ), /* negative, 29 */
LIT64( 0xC01D000000000000 ), /* negative, 30 */
LIT64( 0xC01E000000000000 ), /* negative, 31 */
LIT64( 0xC01F000000000000 ), /* negative, 32 */
LIT64( 0xC03C000000000000 ), /* negative, 61 */
LIT64( 0xC03D000000000000 ), /* negative, 62 */
LIT64( 0xC03E000000000000 ), /* negative, 63 */
LIT64( 0xC03F000000000000 ), /* negative, 64 */
LIT64( 0xC070000000000000 ), /* negative, 113 */
LIT64( 0xC07E000000000000 ), /* negative, 127 */
LIT64( 0xC07F000000000000 ), /* negative, 128 */
LIT64( 0xC080000000000000 ), /* negative, 129 */
LIT64( 0xC3FE000000000000 ), /* negative, 1023 */
LIT64( 0xC3FF000000000000 ), /* negative, 1024 */
LIT64( 0xC400000000000000 ), /* negative, 1025 */
LIT64( 0xFFFD000000000000 ), /* negative, 16382 */
LIT64( 0xFFFE000000000000 ), /* negative, 16383 */
LIT64( 0xFFFF000000000000 ) /* negative, infinity or NaN */
};
 
static const struct { bits64 high, low; } float128P1[ float128NumP1 ] = {
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000001 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFE ) }
};
 
static const struct { bits64 high, low; } float128P2[ float128NumP2 ] = {
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000001 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000002 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000004 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000008 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000010 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000020 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000040 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000080 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000100 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000200 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000400 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000800 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000001000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000002000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000004000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000008000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000010000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000020000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000040000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000080000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000100000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000200000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000400000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000800000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000001000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000002000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000004000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000008000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000010000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000020000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000040000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000080000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000100000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000200000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000400000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000800000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000001000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000002000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000004000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000008000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000010000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000020000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000040000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000080000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000100000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000200000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000400000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000800000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0001000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0002000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0004000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0008000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0010000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0020000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0040000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0080000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0100000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0200000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0400000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0800000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x1000000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x2000000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x4000000000000000 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x8000000000000000 ) },
{ LIT64( 0x0000000000000001 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000002 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000004 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000008 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000010 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000020 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000040 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000080 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000100 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000200 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000400 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000000800 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000001000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000002000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000004000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000008000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000010000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000020000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000040000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000080000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000100000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000200000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000400000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000000800000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000001000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000002000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000004000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000008000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000010000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000020000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000040000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000080000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000100000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000200000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000400000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000000800000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000001000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000002000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000004000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000008000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000010000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000020000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000040000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000080000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000100000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000200000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000400000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000800000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000C00000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000E00000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000F00000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000F80000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FC0000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FE0000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FF0000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FF8000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFC000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFE000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFF000000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFF800000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFC00000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFE00000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFF00000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFF80000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFC0000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFE0000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFF0000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFF8000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFC000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFE000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFF000000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFF800000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFC00000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFE00000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFF00000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFF80000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFC0000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFE0000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFF0000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFF8000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFC000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFE000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFF000 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFF800 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFC00 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFE00 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFF00 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFF80 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFC0 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFE0 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFF0 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFF8 ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFC ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFE ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x0000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x8000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xC000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xE000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF000000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF800000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFC00000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFE00000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF00000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF80000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFC0000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFE0000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF0000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF8000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFC000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFE000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF000000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF800000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFC00000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFE00000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF00000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF80000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFC0000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFE0000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF0000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF8000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFC000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFE000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF000000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF800000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFC00000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFE00000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF00000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF80000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFC0000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFE0000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF0000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF8000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFC000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFE000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF000000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF800000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFC00000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFE00000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF00000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF80000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFC0000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFE0000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF0000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF8000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFC000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFE000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF000 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF800 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFC00 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFE00 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF00 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF80 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFC0 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFE0 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF0 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF8 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFC ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFE ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFD ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFB ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF7 ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFEF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFDF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFBF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF7F ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFEFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFDFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFBFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF7FF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFEFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFDFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFBFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF7FFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFEFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFDFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFBFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF7FFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFEFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFDFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFBFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF7FFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFEFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFDFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFBFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF7FFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFEFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFDFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFBFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF7FFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFEFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFDFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFBFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF7FFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFEFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFDFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFBFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF7FFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFEFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFDFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFBFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF7FFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFEFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFDFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFBFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF7FFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFEFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFDFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFBFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF7FFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFEFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFDFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFBFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF7FFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFEFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFDFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFBFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF7FFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xEFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xDFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xBFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x7FFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFD ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFFB ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFF7 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFEF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFDF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFFBF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFF7F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFEFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFDFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFFBFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFF7FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFEFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFDFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFFBFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFF7FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFEFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFDFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFFBFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFF7FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFEFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFDFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFFBFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFF7FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFEFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFDFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFFBFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFF7FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFEFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFDFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFFBFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFF7FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFEFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFDFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFFBFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFF7FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFEFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFDFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FFBFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FF7FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FEFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FDFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000FBFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000F7FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000EFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000DFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000BFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00007FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00003FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00001FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000007FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000003FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000001FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000007FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000003FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000001FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000007FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000003FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000001FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000000FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000007FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000003FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000001FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000000FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000007FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000003FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000001FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000000007FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000000003FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000000001FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000000000FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000000007FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000000003FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000000001FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000000000FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000007FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000003FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000001FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000000000007FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000000000003FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000000000001FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x00000000000000FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000000000007F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000000000003F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000000000001F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x000000000000000F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000007 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000003 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000001 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x7FFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x3FFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x1FFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0FFFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x07FFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x03FFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x01FFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00FFFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x007FFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x003FFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x001FFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000FFFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0007FFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0003FFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0001FFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000FFFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00007FFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00003FFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00001FFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000FFFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000007FFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000003FFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000001FFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000FFFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000007FFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000003FFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000001FFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000FFFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000007FFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000003FFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000001FFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000000FFFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000007FFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000003FFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000001FFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000000FFFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000007FFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000003FFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000001FFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000FFFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000000007FFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000000003FFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000000001FFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000000000FFFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000000007FFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000000003FFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000000001FFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000000000FFFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000007FFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000003FFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000001FFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000FFF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000000000007FF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000000000003FF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000000000001FF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x00000000000000FF ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000000000007F ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000000000003F ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000000000001F ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x000000000000000F ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000007 ) },
{ LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000003 ) }
};
 
static const uint32 float128NumQInP1 = float128NumQIn * float128NumP1;
static const uint32 float128NumQOutP1 = float128NumQOut * float128NumP1;
 
static float128 float128NextQInP1( sequenceT *sequencePtr )
{
int16 expNum, sigNum;
float128 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z.low = float128P1[ sigNum ].low;
z.high = float128QIn[ expNum ] | float128P1[ sigNum ].high;
++sigNum;
if ( float128NumP1 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float128NumQIn <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static float128 float128NextQOutP1( sequenceT *sequencePtr )
{
int16 expNum, sigNum;
float128 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z.low = float128P1[ sigNum ].low;
z.high = float128QOut[ expNum ] | float128P1[ sigNum ].high;
++sigNum;
if ( float128NumP1 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float128NumQOut <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static const uint32 float128NumQInP2 = float128NumQIn * float128NumP2;
static const uint32 float128NumQOutP2 = float128NumQOut * float128NumP2;
 
static float128 float128NextQInP2( sequenceT *sequencePtr )
{
int16 expNum, sigNum;
float128 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z.low = float128P2[ sigNum ].low;
z.high = float128QIn[ expNum ] | float128P2[ sigNum ].high;
++sigNum;
if ( float128NumP2 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float128NumQIn <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static float128 float128NextQOutP2( sequenceT *sequencePtr )
{
int16 expNum, sigNum;
float128 z;
 
sigNum = sequencePtr->term1Num;
expNum = sequencePtr->expNum;
z.low = float128P2[ sigNum ].low;
z.high = float128QOut[ expNum ] | float128P2[ sigNum ].high;
++sigNum;
if ( float128NumP2 <= sigNum ) {
sigNum = 0;
++expNum;
if ( float128NumQOut <= expNum ) {
expNum = 0;
sequencePtr->done = TRUE;
}
sequencePtr->expNum = expNum;
}
sequencePtr->term1Num = sigNum;
return z;
 
}
 
static float128 float128RandomQOutP3( void )
{
int16 sigNum1, sigNum2;
uint64 sig1Low, sig2Low;
float128 z;
 
sigNum1 = randomUint8() % float128NumP2;
sigNum2 = randomUint8() % float128NumP2;
sig1Low = float128P2[ sigNum1 ].low;
sig2Low = float128P2[ sigNum2 ].low;
z.low = sig1Low + sig2Low;
z.high =
float128QOut[ randomUint8() % float128NumQOut ]
| ( ( float128P2[ sigNum1 ].high
+ float128P2[ sigNum2 ].high
+ ( z.low < sig1Low )
)
& LIT64( 0x0000FFFFFFFFFFFF )
);
return z;
 
}
 
static float128 float128RandomQOutPInf( void )
{
float128 z;
 
z.low = randomUint64();
z.high =
float128QOut[ randomUint8() % float128NumQOut ]
| ( randomUint64() & LIT64( 0x0000FFFFFFFFFFFF ) );
return z;
 
}
 
enum {
float128NumQInfWeightMasks = 14
};
 
static const uint64 float128QInfWeightMasks[ float128NumQInfWeightMasks ] = {
LIT64( 0x7FFF000000000000 ),
LIT64( 0x7FFF000000000000 ),
LIT64( 0x3FFF000000000000 ),
LIT64( 0x1FFF000000000000 ),
LIT64( 0x07FF000000000000 ),
LIT64( 0x07FF000000000000 ),
LIT64( 0x03FF000000000000 ),
LIT64( 0x01FF000000000000 ),
LIT64( 0x00FF000000000000 ),
LIT64( 0x007F000000000000 ),
LIT64( 0x003F000000000000 ),
LIT64( 0x001F000000000000 ),
LIT64( 0x000F000000000000 ),
LIT64( 0x0007000000000000 )
};
 
static const uint64 float128QInfWeightOffsets[ float128NumQInfWeightMasks ] = {
LIT64( 0x0000000000000000 ),
LIT64( 0x0000000000000000 ),
LIT64( 0x2000000000000000 ),
LIT64( 0x3000000000000000 ),
LIT64( 0x3800000000000000 ),
LIT64( 0x3C00000000000000 ),
LIT64( 0x3E00000000000000 ),
LIT64( 0x3F00000000000000 ),
LIT64( 0x3F80000000000000 ),
LIT64( 0x3FC0000000000000 ),
LIT64( 0x3FE0000000000000 ),
LIT64( 0x3FF0000000000000 ),
LIT64( 0x3FF8000000000000 ),
LIT64( 0x3FFC000000000000 )
};
 
static float128 float128RandomQInfP3( void )
{
int16 sigNum1, sigNum2;
uint64 sig1Low, sig2Low;
int8 weightMaskNum;
float128 z;
 
sigNum1 = randomUint8() % float128NumP2;
sigNum2 = randomUint8() % float128NumP2;
sig1Low = float128P2[ sigNum1 ].low;
sig2Low = float128P2[ sigNum2 ].low;
z.low = sig1Low + sig2Low;
weightMaskNum = randomUint8() % float128NumQInfWeightMasks;
z.high =
( ( (uint64) ( randomUint8() & 1 ) )<<63 )
| ( ( ( ( (uint64) randomUint16() )<<48 )
& float128QInfWeightMasks[ weightMaskNum ] )
+ float128QInfWeightOffsets[ weightMaskNum ]
)
| ( ( float128P2[ sigNum1 ].high
+ float128P2[ sigNum2 ].high
+ ( z.low < sig1Low )
)
& LIT64( 0x0000FFFFFFFFFFFF )
);
return z;
 
}
 
static float128 float128RandomQInfPInf( void )
{
int8 weightMaskNum;
float128 z;
 
weightMaskNum = randomUint8() % float128NumQInfWeightMasks;
z.low = randomUint64();
z.high =
( ( (uint64) ( randomUint8() & 1 ) )<<63 )
| ( ( ( ( (uint64) randomUint16() )<<48 )
& float128QInfWeightMasks[ weightMaskNum ] )
+ float128QInfWeightOffsets[ weightMaskNum ]
)
| ( randomUint64() & LIT64( 0x0000FFFFFFFFFFFF ) );
return z;
 
}
 
static float128 float128Random( void )
{
 
switch ( randomUint8() & 7 ) {
case 0:
case 1:
case 2:
return float128RandomQOutP3();
case 3:
return float128RandomQOutPInf();
case 4:
case 5:
case 6:
return float128RandomQInfP3();
case 7:
return float128RandomQInfPInf();
}
 
}
 
#endif
 
static int8 level = 0;
 
void testCases_setLevel( int8 levelIn )
{
 
if ( ( levelIn < 1 ) || ( 2 < levelIn ) ) {
fail( "Invalid testing level: %d", levelIn );
}
level = levelIn;
 
}
 
static int8 sequenceType;
static sequenceT sequenceA, sequenceB;
static int8 subcase;
 
uint32 testCases_total;
flag testCases_done;
 
static float32 current_a_float32;
static float32 current_b_float32;
static float64 current_a_float64;
static float64 current_b_float64;
#ifdef FLOATX80
static floatx80 current_a_floatx80;
static floatx80 current_b_floatx80;
#endif
#ifdef FLOAT128
static float128 current_a_float128;
static float128 current_b_float128;
#endif
 
void testCases_initSequence( int8 sequenceTypeIn )
{
 
sequenceType = sequenceTypeIn;
sequenceA.term2Num = 0;
sequenceA.term1Num = 0;
sequenceA.expNum = 0;
sequenceA.done = FALSE;
sequenceB.term2Num = 0;
sequenceB.term1Num = 0;
sequenceB.expNum = 0;
sequenceB.done = FALSE;
subcase = 0;
switch ( level ) {
case 1:
switch ( sequenceTypeIn ) {
case testCases_sequence_a_int32:
testCases_total = 3 * int32NumP1;
break;
#ifdef BITS64
case testCases_sequence_a_int64:
testCases_total = 3 * int64NumP1;
break;
#endif
case testCases_sequence_a_float32:
testCases_total = 3 * float32NumQOutP1;
break;
case testCases_sequence_ab_float32:
testCases_total = 6 * float32NumQInP1 * float32NumQInP1;
current_a_float32 = float32NextQInP1( &sequenceA );
break;
case testCases_sequence_a_float64:
testCases_total = 3 * float64NumQOutP1;
break;
case testCases_sequence_ab_float64:
testCases_total = 6 * float64NumQInP1 * float64NumQInP1;
current_a_float64 = float64NextQInP1( &sequenceA );
break;
#ifdef FLOATX80
case testCases_sequence_a_floatx80:
testCases_total = 3 * floatx80NumQOutP1;
break;
case testCases_sequence_ab_floatx80:
testCases_total = 6 * floatx80NumQInP1 * floatx80NumQInP1;
current_a_floatx80 = floatx80NextQInP1( &sequenceA );
break;
#endif
#ifdef FLOAT128
case testCases_sequence_a_float128:
testCases_total = 3 * float128NumQOutP1;
break;
case testCases_sequence_ab_float128:
testCases_total = 6 * float128NumQInP1 * float128NumQInP1;
current_a_float128 = float128NextQInP1( &sequenceA );
break;
#endif
}
break;
case 2:
switch ( sequenceTypeIn ) {
case testCases_sequence_a_int32:
testCases_total = 2 * int32NumP2;
break;
#ifdef BITS64
case testCases_sequence_a_int64:
testCases_total = 2 * int64NumP2;
break;
#endif
case testCases_sequence_a_float32:
testCases_total = 2 * float32NumQOutP2;
break;
case testCases_sequence_ab_float32:
testCases_total = 2 * float32NumQInP2 * float32NumQInP2;
current_a_float32 = float32NextQInP2( &sequenceA );
break;
case testCases_sequence_a_float64:
testCases_total = 2 * float64NumQOutP2;
break;
case testCases_sequence_ab_float64:
testCases_total = 2 * float64NumQInP2 * float64NumQInP2;
current_a_float64 = float64NextQInP2( &sequenceA );
break;
#ifdef FLOATX80
case testCases_sequence_a_floatx80:
testCases_total = 2 * floatx80NumQOutP2;
break;
case testCases_sequence_ab_floatx80:
testCases_total = 2 * floatx80NumQInP2 * floatx80NumQInP2;
current_a_floatx80 = floatx80NextQInP2( &sequenceA );
break;
#endif
#ifdef FLOAT128
case testCases_sequence_a_float128:
testCases_total = 2 * float128NumQOutP2;
break;
case testCases_sequence_ab_float128:
testCases_total = 2 * float128NumQInP2 * float128NumQInP2;
current_a_float128 = float128NextQInP2( &sequenceA );
break;
#endif
}
break;
}
testCases_done = FALSE;
 
}
 
int32 testCases_a_int32;
#ifdef BITS64
int64 testCases_a_int64;
#endif
float32 testCases_a_float32;
float32 testCases_b_float32;
float64 testCases_a_float64;
float64 testCases_b_float64;
#ifdef FLOATX80
floatx80 testCases_a_floatx80;
floatx80 testCases_b_floatx80;
#endif
#ifdef FLOAT128
float128 testCases_a_float128;
float128 testCases_b_float128;
#endif
 
void testCases_next( void )
{
 
switch ( level ) {
case 1:
switch ( sequenceType ) {
case testCases_sequence_a_int32:
switch ( subcase ) {
case 0:
testCases_a_int32 = int32RandomP3();
break;
case 1:
testCases_a_int32 = int32RandomPInf();
break;
case 2:
testCases_a_int32 = int32NextP1( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
#ifdef BITS64
case testCases_sequence_a_int64:
switch ( subcase ) {
case 0:
testCases_a_int64 = int64RandomP3();
break;
case 1:
testCases_a_int64 = int64RandomPInf();
break;
case 2:
testCases_a_int64 = int64NextP1( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
#endif
case testCases_sequence_a_float32:
switch ( subcase ) {
case 0:
case 1:
testCases_a_float32 = float32Random();
break;
case 2:
testCases_a_float32 = float32NextQOutP1( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_ab_float32:
switch ( subcase ) {
case 0:
if ( sequenceB.done ) {
sequenceB.done = FALSE;
current_a_float32 = float32NextQInP1( &sequenceA );
}
current_b_float32 = float32NextQInP1( &sequenceB );
case 2:
case 4:
testCases_a_float32 = float32Random();
testCases_b_float32 = float32Random();
break;
case 1:
testCases_a_float32 = current_a_float32;
testCases_b_float32 = float32Random();
break;
case 3:
testCases_a_float32 = float32Random();
testCases_b_float32 = current_b_float32;
break;
case 5:
testCases_a_float32 = current_a_float32;
testCases_b_float32 = current_b_float32;
testCases_done = sequenceA.done & sequenceB.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_a_float64:
switch ( subcase ) {
case 0:
case 1:
testCases_a_float64 = float64Random();
break;
case 2:
testCases_a_float64 = float64NextQOutP1( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_ab_float64:
switch ( subcase ) {
case 0:
if ( sequenceB.done ) {
sequenceB.done = FALSE;
current_a_float64 = float64NextQInP1( &sequenceA );
}
current_b_float64 = float64NextQInP1( &sequenceB );
case 2:
case 4:
testCases_a_float64 = float64Random();
testCases_b_float64 = float64Random();
break;
case 1:
testCases_a_float64 = current_a_float64;
testCases_b_float64 = float64Random();
break;
case 3:
testCases_a_float64 = float64Random();
testCases_b_float64 = current_b_float64;
break;
case 5:
testCases_a_float64 = current_a_float64;
testCases_b_float64 = current_b_float64;
testCases_done = sequenceA.done & sequenceB.done;
subcase = -1;
break;
}
++subcase;
break;
#ifdef FLOATX80
case testCases_sequence_a_floatx80:
switch ( subcase ) {
case 0:
case 1:
testCases_a_floatx80 = floatx80Random();
break;
case 2:
testCases_a_floatx80 = floatx80NextQOutP1( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_ab_floatx80:
switch ( subcase ) {
case 0:
if ( sequenceB.done ) {
sequenceB.done = FALSE;
current_a_floatx80 = floatx80NextQInP1( &sequenceA );
}
current_b_floatx80 = floatx80NextQInP1( &sequenceB );
case 2:
case 4:
testCases_a_floatx80 = floatx80Random();
testCases_b_floatx80 = floatx80Random();
break;
case 1:
testCases_a_floatx80 = current_a_floatx80;
testCases_b_floatx80 = floatx80Random();
break;
case 3:
testCases_a_floatx80 = floatx80Random();
testCases_b_floatx80 = current_b_floatx80;
break;
case 5:
testCases_a_floatx80 = current_a_floatx80;
testCases_b_floatx80 = current_b_floatx80;
testCases_done = sequenceA.done & sequenceB.done;
subcase = -1;
break;
}
++subcase;
break;
#endif
#ifdef FLOAT128
case testCases_sequence_a_float128:
switch ( subcase ) {
case 0:
case 1:
testCases_a_float128 = float128Random();
break;
case 2:
testCases_a_float128 = float128NextQOutP1( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_ab_float128:
switch ( subcase ) {
case 0:
if ( sequenceB.done ) {
sequenceB.done = FALSE;
current_a_float128 = float128NextQInP1( &sequenceA );
}
current_b_float128 = float128NextQInP1( &sequenceB );
case 2:
case 4:
testCases_a_float128 = float128Random();
testCases_b_float128 = float128Random();
break;
case 1:
testCases_a_float128 = current_a_float128;
testCases_b_float128 = float128Random();
break;
case 3:
testCases_a_float128 = float128Random();
testCases_b_float128 = current_b_float128;
break;
case 5:
testCases_a_float128 = current_a_float128;
testCases_b_float128 = current_b_float128;
testCases_done = sequenceA.done & sequenceB.done;
subcase = -1;
break;
}
++subcase;
break;
#endif
}
break;
case 2:
switch ( sequenceType ) {
case testCases_sequence_a_int32:
switch ( subcase ) {
case 0:
testCases_a_int32 = int32RandomP3();
break;
case 2:
testCases_a_int32 = int32RandomPInf();
break;
case 3:
subcase = -1;
case 1:
testCases_a_int32 = int32NextP2( &sequenceA );
testCases_done = sequenceA.done;
break;
}
++subcase;
break;
#ifdef BITS64
case testCases_sequence_a_int64:
switch ( subcase ) {
case 0:
testCases_a_int64 = int64RandomP3();
break;
case 2:
testCases_a_int64 = int64RandomPInf();
break;
case 3:
subcase = -1;
case 1:
testCases_a_int64 = int64NextP2( &sequenceA );
testCases_done = sequenceA.done;
break;
}
++subcase;
break;
#endif
case testCases_sequence_a_float32:
switch ( subcase ) {
case 0:
testCases_a_float32 = float32Random();
break;
case 1:
testCases_a_float32 = float32NextQOutP2( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_ab_float32:
switch ( subcase ) {
case 0:
testCases_a_float32 = float32Random();
testCases_b_float32 = float32Random();
break;
case 1:
if ( sequenceB.done ) {
sequenceB.done = FALSE;
current_a_float32 = float32NextQInP2( &sequenceA );
}
testCases_a_float32 = current_a_float32;
testCases_b_float32 = float32NextQInP2( &sequenceB );
testCases_done = sequenceA.done & sequenceB.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_a_float64:
switch ( subcase ) {
case 0:
testCases_a_float64 = float64Random();
break;
case 1:
testCases_a_float64 = float64NextQOutP2( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_ab_float64:
switch ( subcase ) {
case 0:
testCases_a_float64 = float64Random();
testCases_b_float64 = float64Random();
break;
case 1:
if ( sequenceB.done ) {
sequenceB.done = FALSE;
current_a_float64 = float64NextQInP2( &sequenceA );
}
testCases_a_float64 = current_a_float64;
testCases_b_float64 = float64NextQInP2( &sequenceB );
testCases_done = sequenceA.done & sequenceB.done;
subcase = -1;
break;
}
++subcase;
break;
#ifdef FLOATX80
case testCases_sequence_a_floatx80:
switch ( subcase ) {
case 0:
testCases_a_floatx80 = floatx80Random();
break;
case 1:
testCases_a_floatx80 = floatx80NextQOutP2( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_ab_floatx80:
switch ( subcase ) {
case 0:
testCases_a_floatx80 = floatx80Random();
testCases_b_floatx80 = floatx80Random();
break;
case 1:
if ( sequenceB.done ) {
sequenceB.done = FALSE;
current_a_floatx80 = floatx80NextQInP2( &sequenceA );
}
testCases_a_floatx80 = current_a_floatx80;
testCases_b_floatx80 = floatx80NextQInP2( &sequenceB );
testCases_done = sequenceA.done & sequenceB.done;
subcase = -1;
break;
}
++subcase;
break;
#endif
#ifdef FLOAT128
case testCases_sequence_a_float128:
switch ( subcase ) {
case 0:
testCases_a_float128 = float128Random();
break;
case 1:
testCases_a_float128 = float128NextQOutP2( &sequenceA );
testCases_done = sequenceA.done;
subcase = -1;
break;
}
++subcase;
break;
case testCases_sequence_ab_float128:
switch ( subcase ) {
case 0:
testCases_a_float128 = float128Random();
testCases_b_float128 = float128Random();
break;
case 1:
if ( sequenceB.done ) {
sequenceB.done = FALSE;
current_a_float128 = float128NextQInP2( &sequenceA );
}
testCases_a_float128 = current_a_float128;
testCases_b_float128 = float128NextQInP2( &sequenceB );
testCases_done = sequenceA.done & sequenceB.done;
subcase = -1;
break;
}
++subcase;
break;
#endif
}
break;
}
 
}
 
/writeHex.c
0,0 → 1,189
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
/*
#include <stdio.h>
*/
#include "support.h" // OR1k support C library
#include "milieu.h"
#include "softfloat.h"
#include "writeHex.h"
 
void writeHex_flag( flag a/*, FILE *stream */ )
{
 
putchar( a ? '1' : '0' );
 
}
 
static void writeHex_bits8( bits8 a/*, FILE *stream */ )
{
int digit;
 
digit = ( a>>4 ) & 0xF;
if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
putchar( '0' + digit );
digit = a & 0xF;
if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
putchar( '0' + digit );
 
}
 
static void writeHex_bits12( int16 a/*, FILE *stream */ )
{
int digit;
 
digit = ( a>>8 ) & 0xF;
if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
putchar( '0' + digit );
digit = ( a>>4 ) & 0xF;
if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
putchar( '0' + digit );
digit = a & 0xF;
if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
putchar( '0' + digit );
 
}
 
static void writeHex_bits16( bits16 a/*, FILE *stream */ )
{
int digit;
 
digit = ( a>>12 ) & 0xF;
if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
putchar( '0' + digit );
digit = ( a>>8 ) & 0xF;
if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
putchar( '0' + digit );
digit = ( a>>4 ) & 0xF;
if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
putchar( '0' + digit );
digit = a & 0xF;
if ( 9 < digit ) digit += 'A' - ( '0' + 10 );
putchar( '0' + digit );
 
}
 
void writeHex_bits32( bits32 a/*, FILE *stream */ )
{
 
writeHex_bits16( a>>16 );
writeHex_bits16( a );
 
}
 
#ifdef BITS64
 
void writeHex_bits64( bits64 a/*, FILE *stream */ )
{
 
writeHex_bits32( a>>32 );
writeHex_bits32( a );
 
}
 
#endif
 
void writeHex_float32( float32 a/*, FILE *stream */ )
{
 
putchar( ( ( (sbits32) a ) < 0 ) ? '8' : '0' );
writeHex_bits8( a>>23 );
putchar( '.' );
writeHex_bits8( ( a>>16 ) & 0x7F );
writeHex_bits16( a );
 
}
 
#ifdef BITS64
 
void writeHex_float64( float64 a/*, FILE *stream */ )
{
 
writeHex_bits12( a>>52 );
putchar( '.' );
writeHex_bits12( a>>40 );
writeHex_bits8( a>>32 );
writeHex_bits32( a );
 
}
 
#else
 
void writeHex_float64( float64 a/*, FILE *stream */ )
{
 
writeHex_bits12( a.high>>20 );
putchar( '.' );
writeHex_bits12( a.high>>8 );
writeHex_bits8( a.high );
writeHex_bits32( a.low );
 
}
 
#endif
 
#ifdef FLOATX80
 
void writeHex_floatx80( floatx80 a/*, FILE *stream */ )
{
 
writeHex_bits16( a.high );
putchar( '.' );
writeHex_bits64( a.low );
 
}
 
#endif
 
#ifdef FLOAT128
 
void writeHex_float128( float128 a/*, FILE *stream */ )
{
 
writeHex_bits16( a.high>>48 );
putchar( '.' );
writeHex_bits16( a.high>>32 );
writeHex_bits32( a.high );
writeHex_bits64( a.low );
 
}
 
#endif
 
void writeHex_float_flags( uint8 flags/*, FILE *stream */ )
{
 
putchar( flags & float_flag_invalid ? 'v' : '.' );
putchar( flags & float_flag_divbyzero ? 'z' : '.' );
putchar( flags & float_flag_overflow ? 'o' : '.' );
putchar( flags & float_flag_underflow ? 'u' : '.' );
putchar( flags & float_flag_inexact ? 'x' : '.' );
 
}
 
/systmodes.h
0,0 → 1,46
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
/*
-------------------------------------------------------------------------------
Target-specific function for setting the system's IEC/IEEE floating-point
rounding mode. Other system modes are also initialized as necessary (for
example, exception trapping may be disabled).
-------------------------------------------------------------------------------
*/
void syst_float_set_rounding_mode( int8 );
 
/*
-------------------------------------------------------------------------------
Target-specific function for setting the IEC/IEEE rounding precision of
subsequent extended double-precision operations performed by the system.
-------------------------------------------------------------------------------
*/
void syst_float_set_rounding_precision( int8 );
 
/testsoftfloat.c
0,0 → 1,538
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
/*
#include <stdlib.h>
#include <signal.h>
#include <string.h>
*/
#include "support.h" // OR1k support C library
#include "milieu.h"
#include "fail.h"
#include "softfloat.h"
#include "slowfloat.h"
#include "testCases.h"
#include "testLoops.h"
 
int8 clearFlags( void )
{
int8 flags;
 
flags = float_exception_flags;
float_exception_flags = 0;
return flags;
 
}
 
enum {
INT32_TO_FLOAT32 = 1,
FLOAT32_TO_INT32,
FLOAT32_TO_INT32_ROUND_TO_ZERO,
FLOAT32_ROUND_TO_INT,
FLOAT32_ADD,
FLOAT32_SUB,
FLOAT32_MUL,
FLOAT32_DIV,
FLOAT32_REM,
// FLOAT32_SQRT,
FLOAT32_EQ,
FLOAT32_LE,
FLOAT32_LT,
FLOAT32_EQ_SIGNALING,
FLOAT32_LE_QUIET,
FLOAT32_LT_QUIET,
NUM_FUNCTIONS
};
static struct {
char *name;
int8 numInputs;
flag roundingPrecision, roundingMode;
flag tininessMode, tininessModeAtReducedPrecision;
} functions[ NUM_FUNCTIONS ] = {
{ 0, 0, 0, 0, 0, 0 },
{ "int32_to_float32", 1, FALSE, TRUE, FALSE, FALSE },
{ "float32_to_int32", 1, FALSE, TRUE, FALSE, FALSE },
{ "float32_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE },
{ "float32_round_to_int", 1, FALSE, TRUE, FALSE, FALSE },
{ "float32_add", 2, FALSE, TRUE, FALSE, FALSE },
{ "float32_sub", 2, FALSE, TRUE, FALSE, FALSE },
{ "float32_mul", 2, FALSE, TRUE, TRUE, FALSE },
{ "float32_div", 2, FALSE, TRUE, FALSE, FALSE },
{ "float32_rem", 2, FALSE, FALSE, FALSE, FALSE },
//{ "float32_sqrt", 1, FALSE, TRUE, FALSE, FALSE },
{ "float32_eq", 2, FALSE, FALSE, FALSE, FALSE },
{ "float32_le", 2, FALSE, FALSE, FALSE, FALSE },
{ "float32_lt", 2, FALSE, FALSE, FALSE, FALSE },
{ "float32_eq_signaling", 2, FALSE, FALSE, FALSE, FALSE },
{ "float32_le_quiet", 2, FALSE, FALSE, FALSE, FALSE },
{ "float32_lt_quiet", 2, FALSE, FALSE, FALSE, FALSE }
};
 
enum {
ROUND_NEAREST_EVEN = 1,
ROUND_TO_ZERO,
ROUND_DOWN,
ROUND_UP,
NUM_ROUNDINGMODES
};
enum {
TININESS_BEFORE_ROUNDING = 1,
TININESS_AFTER_ROUNDING,
NUM_TININESSMODES
};
 
static void
testFunctionVariety(
uint8 functionCode,
int8 roundingPrecision,
int8 roundingMode,
int8 tininessMode
)
{
uint8 roundingCode;
int8 tininessCode;
 
functionName = functions[ functionCode ].name;
if ( roundingPrecision == 32 ) {
roundingPrecisionName = "32";
}
else {
roundingPrecisionName = 0;
}
switch ( roundingMode ) {
case 0:
roundingModeName = 0;
roundingCode = float_round_nearest_even;
break;
case ROUND_NEAREST_EVEN:
roundingModeName = "nearest_even";
roundingCode = float_round_nearest_even;
break;
case ROUND_TO_ZERO:
roundingModeName = "to_zero";
roundingCode = float_round_to_zero;
break;
case ROUND_DOWN:
roundingModeName = "down";
roundingCode = float_round_down;
break;
case ROUND_UP:
roundingModeName = "up";
roundingCode = float_round_up;
break;
default: // To keep GCC happy
roundingModeName = "nearest_even";
roundingCode = float_round_nearest_even;
break;
}
float_rounding_mode = roundingCode;
slow_float_rounding_mode = roundingCode;
switch ( tininessMode ) {
case 0:
tininessModeName = 0;
tininessCode = float_tininess_after_rounding;
break;
case TININESS_BEFORE_ROUNDING:
tininessModeName = "before";
tininessCode = float_tininess_before_rounding;
break;
case TININESS_AFTER_ROUNDING:
tininessModeName = "after";
tininessCode = float_tininess_after_rounding;
break;
default:
tininessCode = -1; // to keep GCC happy
}
float_detect_tininess = tininessCode;
slow_float_detect_tininess = tininessCode;
printf( "Testing "/*, stderr*/ );
writeFunctionName( /*stderr*/ );
printf( ".\n"/*, stderr*/ );
switch ( functionCode ) {
case INT32_TO_FLOAT32:
test_a_int32_z_float32( slow_int32_to_float32, int32_to_float32 );
break;
case FLOAT32_TO_INT32:
test_a_float32_z_int32( slow_float32_to_int32, float32_to_int32 );
break;
case FLOAT32_TO_INT32_ROUND_TO_ZERO:
test_a_float32_z_int32(
slow_float32_to_int32_round_to_zero,
float32_to_int32_round_to_zero
);
break;
case FLOAT32_ROUND_TO_INT:
test_az_float32( slow_float32_round_to_int, float32_round_to_int );
break;
case FLOAT32_ADD:
test_abz_float32( slow_float32_add, float32_add );
break;
case FLOAT32_SUB:
test_abz_float32( slow_float32_sub, float32_sub );
break;
case FLOAT32_MUL:
test_abz_float32( slow_float32_mul, float32_mul );
break;
case FLOAT32_DIV:
test_abz_float32( slow_float32_div, float32_div );
break;
case FLOAT32_REM:
test_abz_float32( slow_float32_rem, float32_rem );
break;
// case FLOAT32_SQRT:
// test_az_float32( slow_float32_sqrt, float32_sqrt );
// break;
case FLOAT32_EQ:
test_ab_float32_z_flag( slow_float32_eq, float32_eq );
break;
case FLOAT32_LE:
test_ab_float32_z_flag( slow_float32_le, float32_le );
break;
case FLOAT32_LT:
test_ab_float32_z_flag( slow_float32_lt, float32_lt );
break;
case FLOAT32_EQ_SIGNALING:
test_ab_float32_z_flag(
slow_float32_eq_signaling, float32_eq_signaling );
break;
case FLOAT32_LE_QUIET:
test_ab_float32_z_flag( slow_float32_le_quiet, float32_le_quiet );
break;
case FLOAT32_LT_QUIET:
test_ab_float32_z_flag( slow_float32_lt_quiet, float32_lt_quiet );
break;
}
if ( ( errorStop && anyErrors ) || stop ) exitWithStatus();
 
}
 
static void
testFunction(
uint8 functionCode,
int8 roundingPrecisionIn,
int8 roundingModeIn,
int8 tininessModeIn
)
{
int8 roundingPrecision, roundingMode, tininessMode;
 
roundingPrecision = 32;
for (;;) {
if ( ! functions[ functionCode ].roundingPrecision ) {
roundingPrecision = 0;
}
else if ( roundingPrecisionIn ) {
roundingPrecision = roundingPrecisionIn;
}
for ( roundingMode = 1;
roundingMode < NUM_ROUNDINGMODES;
++roundingMode
) {
if ( ! functions[ functionCode ].roundingMode ) {
roundingMode = 0;
}
else if ( roundingModeIn ) {
roundingMode = roundingModeIn;
}
for ( tininessMode = 1;
tininessMode < NUM_TININESSMODES;
++tininessMode
) {
if ( ( roundingPrecision == 32 )
|| ( roundingPrecision == 64 ) ) {
if ( ! functions[ functionCode ]
.tininessModeAtReducedPrecision
) {
tininessMode = 0;
}
else if ( tininessModeIn ) {
tininessMode = tininessModeIn;
}
}
else {
if ( ! functions[ functionCode ].tininessMode ) {
tininessMode = 0;
}
else if ( tininessModeIn ) {
tininessMode = tininessModeIn;
}
}
testFunctionVariety(
functionCode, roundingPrecision, roundingMode, tininessMode
);
if ( tininessModeIn || ! tininessMode ) break;
}
if ( roundingModeIn || ! roundingMode ) break;
}
if ( roundingPrecisionIn || ! roundingPrecision ) break;
if ( roundingPrecision == 80 ) {
break;
}
else if ( roundingPrecision == 64 ) {
roundingPrecision = 80;
}
else if ( roundingPrecision == 32 ) {
roundingPrecision = 64;
}
}
 
}
 
int
main( int argc, char **argv )
{
//char *argPtr;
flag functionArgument;
uint8 functionCode;
int8 operands, roundingPrecision, roundingMode, tininessMode;
/*
fail_programName = "testsoftfloat";
if ( argc <= 1 ) goto writeHelpMessage;
*/
testCases_setLevel( 1 );
trueName = "true";
testName = "soft";
errorStop = FALSE;
forever = FALSE;
maxErrorCount = 5000;
trueFlagsPtr = &slow_float_exception_flags;
testFlagsFunctionPtr = clearFlags;
functionArgument = TRUE;
functionCode = 0;
operands = 0;
roundingPrecision = 0;
roundingMode = 0;
tininessMode = 0;
/*
--argc;
++argv;
while ( argc && ( argPtr = argv[ 0 ] ) ) {
if ( argPtr[ 0 ] == '-' ) ++argPtr;
if ( strcmp( argPtr, "help" ) == 0 ) {
writeHelpMessage:
fputs(
"testsoftfloat [<option>...] <function>\n"
" <option>: (* is default)\n"
" -help --Write this message and exit.\n"
" -level <num> --Testing level <num> (1 or 2).\n"
" * -level 1\n"
" -errors <num> --Stop each function test after <num> errors.\n"
" * -errors 20\n"
" -errorstop --Exit after first function with any error.\n"
" -forever --Test one function repeatedly (implies `-level 2').\n"
#ifdef FLOATX80
" -precision32 --Only test rounding precision equivalent to float32.\n"
" -precision64 --Only test rounding precision equivalent to float64.\n"
" -precision80 --Only test maximum rounding precision.\n"
#endif
" -nearesteven --Only test rounding to nearest/even.\n"
" -tozero --Only test rounding to zero.\n"
" -down --Only test rounding down.\n"
" -up --Only test rounding up.\n"
" -tininessbefore --Only test underflow tininess before rounding.\n"
" -tininessafter --Only test underflow tininess after rounding.\n"
" <function>:\n"
" int32_to_<float> <float>_add <float>_eq\n"
" <float>_to_int32 <float>_sub <float>_le\n"
" <float>_to_int32_round_to_zero <float>_mul <float>_lt\n"
#ifdef BITS64
" int64_to_<float> <float>_div <float>_eq_signaling\n"
" <float>_to_int64 <float>_rem <float>_le_quiet\n"
" <float>_to_int64_round_to_zero <float>_lt_quiet\n"
" <float>_to_<float>\n"
" <float>_round_to_int\n"
" <float>_sqrt\n"
#else
" <float>_to_<float> <float>_div <float>_eq_signaling\n"
" <float>_round_to_int <float>_rem <float>_le_quiet\n"
" <float>_sqrt <float>_lt_quiet\n"
#endif
" -all1 --All 1-operand functions.\n"
" -all2 --All 2-operand functions.\n"
" -all --All functions.\n"
" <float>:\n"
" float32 --Single precision.\n"
" float64 --Double precision.\n"
#ifdef FLOATX80
" floatx80 --Extended double precision.\n"
#endif
#ifdef FLOAT128
" float128 --Quadruple precision.\n"
#endif
,
stdout
);
return EXIT_SUCCESS;
}
else if ( strcmp( argPtr, "level" ) == 0 ) {
if ( argc < 2 ) goto optionError;
testCases_setLevel( atoi( argv[ 1 ] ) );
--argc;
++argv;
}
else if ( strcmp( argPtr, "level1" ) == 0 ) {
testCases_setLevel( 1 );
}
else if ( strcmp( argPtr, "level2" ) == 0 ) {
testCases_setLevel( 2 );
}
else if ( strcmp( argPtr, "errors" ) == 0 ) {
if ( argc < 2 ) {
optionError:
fail( "`%s' option requires numeric argument", argv[ 0 ] );
}
maxErrorCount = atoi( argv[ 1 ] );
--argc;
++argv;
}
else if ( strcmp( argPtr, "errorstop" ) == 0 ) {
errorStop = TRUE;
}
else if ( strcmp( argPtr, "forever" ) == 0 ) {
testCases_setLevel( 2 );
forever = TRUE;
}
#ifdef FLOATX80
else if ( strcmp( argPtr, "precision32" ) == 0 ) {
roundingPrecision = 32;
}
else if ( strcmp( argPtr, "precision64" ) == 0 ) {
roundingPrecision = 64;
}
else if ( strcmp( argPtr, "precision80" ) == 0 ) {
roundingPrecision = 80;
}
#endif
else if ( ( strcmp( argPtr, "nearesteven" ) == 0 )
|| ( strcmp( argPtr, "nearest_even" ) == 0 ) ) {
roundingMode = ROUND_NEAREST_EVEN;
}
else if ( ( strcmp( argPtr, "tozero" ) == 0 )
|| ( strcmp( argPtr, "to_zero" ) == 0 ) ) {
roundingMode = ROUND_TO_ZERO;
}
else if ( strcmp( argPtr, "down" ) == 0 ) {
roundingMode = ROUND_DOWN;
}
else if ( strcmp( argPtr, "up" ) == 0 ) {
roundingMode = ROUND_UP;
}
else if ( strcmp( argPtr, "tininessbefore" ) == 0 ) {
tininessMode = TININESS_BEFORE_ROUNDING;
}
else if ( strcmp( argPtr, "tininessafter" ) == 0 ) {
tininessMode = TININESS_AFTER_ROUNDING;
}
else if ( strcmp( argPtr, "all1" ) == 0 ) {
functionArgument = TRUE;
functionCode = 0;
operands = 1;
}
else if ( strcmp( argPtr, "all2" ) == 0 ) {
functionArgument = TRUE;
functionCode = 0;
operands = 2;
}
else if ( strcmp( argPtr, "all" ) == 0 ) {
functionArgument = TRUE;
functionCode = 0;
operands = 0;
}
else {
for ( functionCode = 1;
functionCode < NUM_FUNCTIONS;
++functionCode
) {
if ( strcmp( argPtr, functions[ functionCode ].name ) == 0 ) {
break;
}
}
if ( functionCode == NUM_FUNCTIONS ) {
fail( "Invalid option or function `%s'", argv[ 0 ] );
}
functionArgument = TRUE;
}
--argc;
++argv;
}
 
*/
 
// Test just a single function
if ( functionCode ) {
testFunction(
functionCode, roundingPrecision, roundingMode, tininessMode );
}
else {
if ( operands == 1 ) {
for ( functionCode = 1;
functionCode < NUM_FUNCTIONS;
++functionCode
) {
if ( functions[ functionCode ].numInputs == 1 ) {
testFunction(
functionCode,
roundingPrecision,
roundingMode,
tininessMode
);
}
}
}
else if ( operands == 2 ) {
for ( functionCode = 1;
functionCode < NUM_FUNCTIONS;
++functionCode
) {
if ( functions[ functionCode ].numInputs == 2 ) {
testFunction(
functionCode,
roundingPrecision,
roundingMode,
tininessMode
);
}
}
}
else {
for ( functionCode = 1;
functionCode < NUM_FUNCTIONS;
++functionCode
) {
testFunction(
functionCode, roundingPrecision, roundingMode, tininessMode
);
}
}
}
exitWithStatus();
// Shouldn't reach here.
return 1;
}
 
/testLoops.h
0,0 → 1,147
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
//#include <stdio.h>
 
extern volatile flag stop;
 
extern char *trueName, *testName;
extern flag forever, errorStop;
extern uint32 maxErrorCount;
extern flag checkNaNs;
extern int8 *trueFlagsPtr;
extern int8 ( *testFlagsFunctionPtr )( void );
extern char *functionName;
extern char *roundingPrecisionName, *roundingModeName, *tininessModeName;
extern flag anyErrors;
 
void writeFunctionName( /*FILE * */ );
void exitWithStatus( void );
 
void test_a_int32_z_float32( float32 ( int32 ), float32 ( int32 ) );
void test_a_int32_z_float64( float64 ( int32 ), float64 ( int32 ) );
#ifdef FLOATX80
void test_a_int32_z_floatx80( floatx80 ( int32 ), floatx80 ( int32 ) );
#endif
#ifdef FLOAT128
void test_a_int32_z_float128( float128 ( int32 ), float128 ( int32 ) );
#endif
#ifdef BITS64
void test_a_int64_z_float32( float32 ( int64 ), float32 ( int64 ) );
void test_a_int64_z_float64( float64 ( int64 ), float64 ( int64 ) );
#ifdef FLOATX80
void test_a_int64_z_floatx80( floatx80 ( int64 ), floatx80 ( int64 ) );
#endif
#ifdef FLOAT128
void test_a_int64_z_float128( float128 ( int64 ), float128 ( int64 ) );
#endif
#endif
 
void test_a_float32_z_int32( int32 ( float32 ), int32 ( float32 ) );
#ifdef BITS64
void test_a_float32_z_int64( int64 ( float32 ), int64 ( float32 ) );
#endif
void test_a_float32_z_float64( float64 ( float32 ), float64 ( float32 ) );
#ifdef FLOATX80
void test_a_float32_z_floatx80( floatx80 ( float32 ), floatx80 ( float32 ) );
#endif
#ifdef FLOAT128
void test_a_float32_z_float128( float128 ( float32 ), float128 ( float32 ) );
#endif
void test_az_float32( float32 ( float32 ), float32 ( float32 ) );
void
test_ab_float32_z_flag(
flag ( float32, float32 ), flag ( float32, float32 ) );
void
test_abz_float32(
float32 ( float32, float32 ), float32 ( float32, float32 ) );
 
void test_a_float64_z_int32( int32 ( float64 ), int32 ( float64 ) );
#ifdef BITS64
void test_a_float64_z_int64( int64 ( float64 ), int64 ( float64 ) );
#endif
void test_a_float64_z_float32( float32 ( float64 ), float32 ( float64 ) );
#ifdef FLOATX80
void test_a_float64_z_floatx80( floatx80 ( float64 ), floatx80 ( float64 ) );
#endif
#ifdef FLOAT128
void test_a_float64_z_float128( float128 ( float64 ), float128 ( float64 ) );
#endif
void test_az_float64( float64 ( float64 ), float64 ( float64 ) );
void
test_ab_float64_z_flag(
flag ( float64, float64 ), flag ( float64, float64 ) );
void
test_abz_float64(
float64 ( float64, float64 ), float64 ( float64, float64 ) );
 
#ifdef FLOATX80
 
void test_a_floatx80_z_int32( int32 ( floatx80 ), int32 ( floatx80 ) );
#ifdef BITS64
void test_a_floatx80_z_int64( int64 ( floatx80 ), int64 ( floatx80 ) );
#endif
void test_a_floatx80_z_float32( float32 ( floatx80 ), float32 ( floatx80 ) );
void test_a_floatx80_z_float64( float64 ( floatx80 ), float64 ( floatx80 ) );
#ifdef FLOAT128
void
test_a_floatx80_z_float128( float128 ( floatx80 ), float128 ( floatx80 ) );
#endif
void test_az_floatx80( floatx80 ( floatx80 ), floatx80 ( floatx80 ) );
void
test_ab_floatx80_z_flag(
flag ( floatx80, floatx80 ), flag ( floatx80, floatx80 ) );
void
test_abz_floatx80(
floatx80 ( floatx80, floatx80 ), floatx80 ( floatx80, floatx80 ) );
 
#endif
 
#ifdef FLOAT128
 
void test_a_float128_z_int32( int32 ( float128 ), int32 ( float128 ) );
#ifdef BITS64
void test_a_float128_z_int64( int64 ( float128 ), int64 ( float128 ) );
#endif
void test_a_float128_z_float32( float32 ( float128 ), float32 ( float128 ) );
void test_a_float128_z_float64( float64 ( float128 ), float64 ( float128 ) );
#ifdef FLOATX80
void
test_a_float128_z_floatx80( floatx80 ( float128 ), floatx80 ( float128 ) );
#endif
void test_az_float128( float128 ( float128 ), float128 ( float128 ) );
void
test_ab_float128_z_flag(
flag ( float128, float128 ), flag ( float128, float128 ) );
void
test_abz_float128(
float128 ( float128, float128 ), float128 ( float128, float128 ) );
 
#endif
 
/softfloat.c
0,0 → 1,6328
 
/*============================================================================
 
This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
Package, Release 2b.
 
Written by John R. Hauser. This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704. Funding was partially provided by the
National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
arithmetic/SoftFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
=============================================================================*/
 
#include "milieu.h"
#include "softfloat.h"
 
/*----------------------------------------------------------------------------
| Floating-point rounding mode, extended double-precision rounding precision,
| and exception flags.
*----------------------------------------------------------------------------*/
int8 float_rounding_mode = float_round_nearest_even;
int8 float_exception_flags = 0;
#ifdef FLOATX80
int8 floatx80_rounding_precision = 80;
#endif
 
/*----------------------------------------------------------------------------
| Primitive arithmetic functions, including multi-word arithmetic, and
| division and square root approximations. (Can be specialized to target if
| desired.)
*----------------------------------------------------------------------------*/
//#include "softfloat-macros"
 
/*----------------------------------------------------------------------------
| Shifts `a' right by the number of bits given in `count'. If any nonzero
| bits are shifted off, they are ``jammed'' into the least significant bit of
| the result by setting the least significant bit to 1. The value of `count'
| can be arbitrarily large; in particular, if `count' is greater than 32, the
| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
| The result is stored in the location pointed to by `zPtr'.
*----------------------------------------------------------------------------*/
 
INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
{
bits32 z;
 
if ( count == 0 ) {
z = a;
}
else if ( count < 32 ) {
z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
}
else {
z = ( a != 0 );
}
*zPtr = z;
 
}
 
/*----------------------------------------------------------------------------
| Shifts `a' right by the number of bits given in `count'. If any nonzero
| bits are shifted off, they are ``jammed'' into the least significant bit of
| the result by setting the least significant bit to 1. The value of `count'
| can be arbitrarily large; in particular, if `count' is greater than 64, the
| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
| The result is stored in the location pointed to by `zPtr'.
*----------------------------------------------------------------------------*/
 
INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
{
bits64 z;
 
if ( count == 0 ) {
z = a;
}
else if ( count < 64 ) {
z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
}
else {
z = ( a != 0 );
}
*zPtr = z;
 
}
 
/*----------------------------------------------------------------------------
| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
| _plus_ the number of bits given in `count'. The shifted result is at most
| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
| bits shifted off form a second 64-bit result as follows: The _last_ bit
| shifted off is the most-significant bit of the extra result, and the other
| 63 bits of the extra result are all zero if and only if _all_but_the_last_
| bits shifted off were all zero. This extra result is stored in the location
| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
| (This routine makes more sense if `a0' and `a1' are considered to form
| a fixed-point value with binary point between `a0' and `a1'. This fixed-
| point value is shifted right by the number of bits given in `count', and
| the integer part of the result is returned at the location pointed to by
| `z0Ptr'. The fractional part of the result may be slightly corrupted as
| described above, and is returned at the location pointed to by `z1Ptr'.)
*----------------------------------------------------------------------------*/
 
INLINE void
shift64ExtraRightJamming(
bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
{
bits64 z0, z1;
int8 negCount = ( - count ) & 63;
 
if ( count == 0 ) {
z1 = a1;
z0 = a0;
}
else if ( count < 64 ) {
z1 = ( a0<<negCount ) | ( a1 != 0 );
z0 = a0>>count;
}
else {
if ( count == 64 ) {
z1 = a0 | ( a1 != 0 );
}
else {
z1 = ( ( a0 | a1 ) != 0 );
}
z0 = 0;
}
*z1Ptr = z1;
*z0Ptr = z0;
 
}
 
/*----------------------------------------------------------------------------
| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
| number of bits given in `count'. Any bits shifted off are lost. The value
| of `count' can be arbitrarily large; in particular, if `count' is greater
| than 128, the result will be 0. The result is broken into two 64-bit pieces
| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE void
shift128Right(
bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
{
bits64 z0, z1;
int8 negCount = ( - count ) & 63;
 
if ( count == 0 ) {
z1 = a1;
z0 = a0;
}
else if ( count < 64 ) {
z1 = ( a0<<negCount ) | ( a1>>count );
z0 = a0>>count;
}
else {
z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
z0 = 0;
}
*z1Ptr = z1;
*z0Ptr = z0;
 
}
*/
/*----------------------------------------------------------------------------
| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
| number of bits given in `count'. If any nonzero bits are shifted off, they
| are ``jammed'' into the least significant bit of the result by setting the
| least significant bit to 1. The value of `count' can be arbitrarily large;
| in particular, if `count' is greater than 128, the result will be either
| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
| nonzero. The result is broken into two 64-bit pieces which are stored at
| the locations pointed to by `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE void
shift128RightJamming(
bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
{
bits64 z0, z1;
int8 negCount = ( - count ) & 63;
 
if ( count == 0 ) {
z1 = a1;
z0 = a0;
}
else if ( count < 64 ) {
z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
z0 = a0>>count;
}
else {
if ( count == 64 ) {
z1 = a0 | ( a1 != 0 );
}
else if ( count < 128 ) {
z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
}
else {
z1 = ( ( a0 | a1 ) != 0 );
}
z0 = 0;
}
*z1Ptr = z1;
*z0Ptr = z0;
 
}
*/
/*----------------------------------------------------------------------------
| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
| by 64 _plus_ the number of bits given in `count'. The shifted result is
| at most 128 nonzero bits; these are broken into two 64-bit pieces which are
| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
| off form a third 64-bit result as follows: The _last_ bit shifted off is
| the most-significant bit of the extra result, and the other 63 bits of the
| extra result are all zero if and only if _all_but_the_last_ bits shifted off
| were all zero. This extra result is stored in the location pointed to by
| `z2Ptr'. The value of `count' can be arbitrarily large.
| (This routine makes more sense if `a0', `a1', and `a2' are considered
| to form a fixed-point value with binary point between `a1' and `a2'. This
| fixed-point value is shifted right by the number of bits given in `count',
| and the integer part of the result is returned at the locations pointed to
| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
| corrupted as described above, and is returned at the location pointed to by
| `z2Ptr'.)
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE void
shift128ExtraRightJamming(
bits64 a0,
bits64 a1,
bits64 a2,
int16 count,
bits64 *z0Ptr,
bits64 *z1Ptr,
bits64 *z2Ptr
)
{
bits64 z0, z1, z2;
int8 negCount = ( - count ) & 63;
 
if ( count == 0 ) {
z2 = a2;
z1 = a1;
z0 = a0;
}
else {
if ( count < 64 ) {
z2 = a1<<negCount;
z1 = ( a0<<negCount ) | ( a1>>count );
z0 = a0>>count;
}
else {
if ( count == 64 ) {
z2 = a1;
z1 = a0;
}
else {
a2 |= a1;
if ( count < 128 ) {
z2 = a0<<negCount;
z1 = a0>>( count & 63 );
}
else {
z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
z1 = 0;
}
}
z0 = 0;
}
z2 |= ( a2 != 0 );
}
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
 
}
*/
/*----------------------------------------------------------------------------
| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
| number of bits given in `count'. Any bits shifted off are lost. The value
| of `count' must be less than 64. The result is broken into two 64-bit
| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE void
shortShift128Left(
bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
{
 
*z1Ptr = a1<<count;
*z0Ptr =
( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
 
}
*/
/*----------------------------------------------------------------------------
| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
| by the number of bits given in `count'. Any bits shifted off are lost.
| The value of `count' must be less than 64. The result is broken into three
| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
| `z1Ptr', and `z2Ptr'.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE void
shortShift192Left(
bits64 a0,
bits64 a1,
bits64 a2,
int16 count,
bits64 *z0Ptr,
bits64 *z1Ptr,
bits64 *z2Ptr
)
{
bits64 z0, z1, z2;
int8 negCount;
 
z2 = a2<<count;
z1 = a1<<count;
z0 = a0<<count;
if ( 0 < count ) {
negCount = ( ( - count ) & 63 );
z1 |= a2>>negCount;
z0 |= a1>>negCount;
}
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
 
}
*/
/*----------------------------------------------------------------------------
| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
| any carry out is lost. The result is broken into two 64-bit pieces which
| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
 
INLINE void
add128(
bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
{
bits64 z1;
 
z1 = a1 + b1;
*z1Ptr = z1;
*z0Ptr = a0 + b0 + ( z1 < a1 );
 
}
 
/*----------------------------------------------------------------------------
| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
| modulo 2^192, so any carry out is lost. The result is broken into three
| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
| `z1Ptr', and `z2Ptr'.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE void
add192(
bits64 a0,
bits64 a1,
bits64 a2,
bits64 b0,
bits64 b1,
bits64 b2,
bits64 *z0Ptr,
bits64 *z1Ptr,
bits64 *z2Ptr
)
{
bits64 z0, z1, z2;
int8 carry0, carry1;
 
z2 = a2 + b2;
carry1 = ( z2 < a2 );
z1 = a1 + b1;
carry0 = ( z1 < a1 );
z0 = a0 + b0;
z1 += carry1;
z0 += ( z1 < carry1 );
z0 += carry0;
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
 
}
*/
/*----------------------------------------------------------------------------
| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
| 2^128, so any borrow out (carry out) is lost. The result is broken into two
| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
| `z1Ptr'.
*----------------------------------------------------------------------------*/
 
INLINE void
sub128(
bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
{
 
*z1Ptr = a1 - b1;
*z0Ptr = a0 - b0 - ( a1 < b1 );
 
}
 
/*----------------------------------------------------------------------------
| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
| from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
| result is broken into three 64-bit pieces which are stored at the locations
| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE void
sub192(
bits64 a0,
bits64 a1,
bits64 a2,
bits64 b0,
bits64 b1,
bits64 b2,
bits64 *z0Ptr,
bits64 *z1Ptr,
bits64 *z2Ptr
)
{
bits64 z0, z1, z2;
int8 borrow0, borrow1;
 
z2 = a2 - b2;
borrow1 = ( a2 < b2 );
z1 = a1 - b1;
borrow0 = ( a1 < b1 );
z0 = a0 - b0;
z0 -= ( z1 < borrow1 );
z1 -= borrow1;
z0 -= borrow0;
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
 
}
*/
/*----------------------------------------------------------------------------
| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
| into two 64-bit pieces which are stored at the locations pointed to by
| `z0Ptr' and `z1Ptr'.
*----------------------------------------------------------------------------*/
 
INLINE void
mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
{
bits32 aHigh, aLow, bHigh, bLow;
bits64 z0, zMiddleA, zMiddleB, z1;
 
aLow = a;
aHigh = a>>32;
bLow = b;
bHigh = b>>32;
z1 = ( (bits64) aLow ) * bLow;
zMiddleA = ( (bits64) aLow ) * bHigh;
zMiddleB = ( (bits64) aHigh ) * bLow;
z0 = ( (bits64) aHigh ) * bHigh;
zMiddleA += zMiddleB;
z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
zMiddleA <<= 32;
z1 += zMiddleA;
z0 += ( z1 < zMiddleA );
*z1Ptr = z1;
*z0Ptr = z0;
 
}
 
/*----------------------------------------------------------------------------
| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
| `b' to obtain a 192-bit product. The product is broken into three 64-bit
| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
| `z2Ptr'.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE void
mul128By64To192(
bits64 a0,
bits64 a1,
bits64 b,
bits64 *z0Ptr,
bits64 *z1Ptr,
bits64 *z2Ptr
)
{
bits64 z0, z1, z2, more1;
 
mul64To128( a1, b, &z1, &z2 );
mul64To128( a0, b, &z0, &more1 );
add128( z0, more1, 0, z1, &z0, &z1 );
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
 
}
*/
/*----------------------------------------------------------------------------
| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
| product. The product is broken into four 64-bit pieces which are stored at
| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE void
mul128To256(
bits64 a0,
bits64 a1,
bits64 b0,
bits64 b1,
bits64 *z0Ptr,
bits64 *z1Ptr,
bits64 *z2Ptr,
bits64 *z3Ptr
)
{
bits64 z0, z1, z2, z3;
bits64 more1, more2;
 
mul64To128( a1, b1, &z2, &z3 );
mul64To128( a1, b0, &z1, &more2 );
add128( z1, more2, 0, z2, &z1, &z2 );
mul64To128( a0, b0, &z0, &more1 );
add128( z0, more1, 0, z1, &z0, &z1 );
mul64To128( a0, b1, &more1, &more2 );
add128( more1, more2, 0, z2, &more1, &z2 );
add128( z0, z1, 0, more1, &z0, &z1 );
*z3Ptr = z3;
*z2Ptr = z2;
*z1Ptr = z1;
*z0Ptr = z0;
 
}
*/
/*----------------------------------------------------------------------------
| Returns an approximation to the 64-bit integer quotient obtained by dividing
| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The
| divisor `b' must be at least 2^63. If q is the exact quotient truncated
| toward zero, the approximation returned lies between q and q + 2 inclusive.
| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
| unsigned integer is returned.
*----------------------------------------------------------------------------*/
 
static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
{
bits64 b0, b1;
bits64 rem0, rem1, term0, term1;
bits64 z;
 
if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
b0 = b>>32;
z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
mul64To128( b, z, &term0, &term1 );
sub128( a0, a1, term0, term1, &rem0, &rem1 );
while ( ( (sbits64) rem0 ) < 0 ) {
z -= LIT64( 0x100000000 );
b1 = b<<32;
add128( rem0, rem1, b0, b1, &rem0, &rem1 );
}
rem0 = ( rem0<<32 ) | ( rem1>>32 );
z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns an approximation to the square root of the 32-bit significand given
| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
| `aExp' (the least significant bit) is 1, the integer returned approximates
| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
| case, the approximation returned lies strictly within +/-2 of the exact
| value.
*----------------------------------------------------------------------------*/
 
static bits32 estimateSqrt32( int16 aExp, bits32 a )
{
static const bits16 sqrtOddAdjustments[] = {
0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
};
static const bits16 sqrtEvenAdjustments[] = {
0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
};
int8 index;
bits32 z;
 
index = ( a>>27 ) & 15;
if ( aExp & 1 ) {
z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
z = ( ( a / z )<<14 ) + ( z<<15 );
a >>= 1;
}
else {
z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
z = a / z + z;
z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
}
return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the number of leading 0 bits before the most-significant 1 bit of
| `a'. If `a' is zero, 32 is returned.
*----------------------------------------------------------------------------*/
 
static int8 countLeadingZeros32( bits32 a )
{
static const int8 countLeadingZerosHigh[] = {
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
int8 shiftCount;
 
shiftCount = 0;
if ( a < 0x10000 ) {
shiftCount += 16;
a <<= 16;
}
if ( a < 0x1000000 ) {
shiftCount += 8;
a <<= 8;
}
shiftCount += countLeadingZerosHigh[ a>>24 ];
return shiftCount;
 
}
 
/*----------------------------------------------------------------------------
| Returns the number of leading 0 bits before the most-significant 1 bit of
| `a'. If `a' is zero, 64 is returned.
*----------------------------------------------------------------------------*/
 
static int8 countLeadingZeros64( bits64 a )
{
int8 shiftCount;
 
shiftCount = 0;
if ( a < ( (bits64) 1 )<<32 ) {
shiftCount += 32;
}
else {
a >>= 32;
}
shiftCount += countLeadingZeros32( a );
return shiftCount;
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
| is equal to the 128-bit value formed by concatenating `b0' and `b1'.
| Otherwise, returns 0.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
{
 
return ( a0 == b0 ) && ( a1 == b1 );
 
}
*/
/*----------------------------------------------------------------------------
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
| than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
| Otherwise, returns 0.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
{
 
return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
 
}
*/
/*----------------------------------------------------------------------------
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
| returns 0.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
{
 
return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
 
}
*/
/*----------------------------------------------------------------------------
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
| not equal to the 128-bit value formed by concatenating `b0' and `b1'.
| Otherwise, returns 0.
*----------------------------------------------------------------------------*/
// Not used - commenting out to stop werrors during compile
/*
INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
{
 
return ( a0 != b0 ) || ( a1 != b1 );
 
}
*/
/*----------------------------------------------------------------------------
| Functions and definitions to determine: (1) whether tininess for underflow
| is detected before or after rounding by default, (2) what (if anything)
| happens when exceptions are raised, (3) how signaling NaNs are distinguished
| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
| are propagated from function inputs to output. These details are target-
| specific.
*----------------------------------------------------------------------------*/
//#include "softfloat-specialize"
 
/*----------------------------------------------------------------------------
| Underflow tininess-detection mode, statically initialized to default value.
| (The declaration in `softfloat.h' must match the `int8' type here.)
*----------------------------------------------------------------------------*/
int8 float_detect_tininess = float_tininess_after_rounding;
 
/*----------------------------------------------------------------------------
| Raises the exceptions specified by `flags'. Floating-point traps can be
| defined here if desired. It is currently not possible for such a trap
| to substitute a result value. If traps are not implemented, this routine
| should be simply `float_exception_flags |= flags;'.
*----------------------------------------------------------------------------*/
 
void float_raise( int8 flags )
{
 
float_exception_flags |= flags;
 
}
 
/*----------------------------------------------------------------------------
| Internal canonical NaN format.
*----------------------------------------------------------------------------*/
typedef struct {
flag sign;
bits64 high, low;
} commonNaNT;
 
/*----------------------------------------------------------------------------
| The pattern for a default generated single-precision NaN.
*----------------------------------------------------------------------------*/
#define float32_default_nan 0xFFC00000
 
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is a NaN;
| otherwise returns 0.
*----------------------------------------------------------------------------*/
 
flag float32_is_nan( float32 a )
{
 
return ( 0xFF000000 < (bits32) ( a<<1 ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is a signaling
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
 
flag float32_is_signaling_nan( float32 a )
{
 
return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point NaN
| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
 
static commonNaNT float32ToCommonNaN( float32 a )
{
commonNaNT z;
 
if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
z.sign = a>>31;
z.low = 0;
z.high = ( (bits64) a )<<41;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the single-
| precision floating-point format.
*----------------------------------------------------------------------------*/
 
static float32 commonNaNToFloat32( commonNaNT a )
{
 
return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
 
}
 
/*----------------------------------------------------------------------------
| Takes two single-precision floating-point values `a' and `b', one of which
| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
 
static float32 propagateFloat32NaN( float32 a, float32 b )
{
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
 
aIsNaN = float32_is_nan( a );
aIsSignalingNaN = float32_is_signaling_nan( a );
bIsNaN = float32_is_nan( b );
bIsSignalingNaN = float32_is_signaling_nan( b );
a |= 0x00400000;
b |= 0x00400000;
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
if ( aIsSignalingNaN ) {
if ( bIsSignalingNaN ) goto returnLargerSignificand;
return bIsNaN ? b : a;
}
else if ( aIsNaN ) {
if ( bIsSignalingNaN | ! bIsNaN ) return a;
returnLargerSignificand:
if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
return ( a < b ) ? a : b;
}
else {
return b;
}
 
}
 
/*----------------------------------------------------------------------------
| The pattern for a default generated double-precision NaN.
*----------------------------------------------------------------------------*/
#define float64_default_nan LIT64( 0xFFF8000000000000 )
 
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is a NaN;
| otherwise returns 0.
*----------------------------------------------------------------------------*/
 
flag float64_is_nan( float64 a )
{
 
return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is a signaling
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
 
flag float64_is_signaling_nan( float64 a )
{
 
return
( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
&& ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point NaN
| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
 
static commonNaNT float64ToCommonNaN( float64 a )
{
commonNaNT z;
 
if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
z.sign = a>>63;
z.low = 0;
z.high = a<<12;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the double-
| precision floating-point format.
*----------------------------------------------------------------------------*/
 
static float64 commonNaNToFloat64( commonNaNT a )
{
 
return
( ( (bits64) a.sign )<<63 )
| LIT64( 0x7FF8000000000000 )
| ( a.high>>12 );
 
}
 
/*----------------------------------------------------------------------------
| Takes two double-precision floating-point values `a' and `b', one of which
| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
 
static float64 propagateFloat64NaN( float64 a, float64 b )
{
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
 
aIsNaN = float64_is_nan( a );
aIsSignalingNaN = float64_is_signaling_nan( a );
bIsNaN = float64_is_nan( b );
bIsSignalingNaN = float64_is_signaling_nan( b );
a |= LIT64( 0x0008000000000000 );
b |= LIT64( 0x0008000000000000 );
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
if ( aIsSignalingNaN ) {
if ( bIsSignalingNaN ) goto returnLargerSignificand;
return bIsNaN ? b : a;
}
else if ( aIsNaN ) {
if ( bIsSignalingNaN | ! bIsNaN ) return a;
returnLargerSignificand:
if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
return ( a < b ) ? a : b;
}
else {
return b;
}
 
}
 
#ifdef FLOATX80
 
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN. The
| `high' and `low' values hold the most- and least-significant bits,
| respectively.
*----------------------------------------------------------------------------*/
#define floatx80_default_nan_high 0xFFFF
#define floatx80_default_nan_low LIT64( 0xC000000000000000 )
 
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is a
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
 
flag floatx80_is_nan( floatx80 a )
{
 
return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is a
| signaling NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
 
flag floatx80_is_signaling_nan( floatx80 a )
{
bits64 aLow;
 
aLow = a.low & ~ LIT64( 0x4000000000000000 );
return
( ( a.high & 0x7FFF ) == 0x7FFF )
&& (bits64) ( aLow<<1 )
&& ( a.low == aLow );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
| invalid exception is raised.
*----------------------------------------------------------------------------*/
 
static commonNaNT floatx80ToCommonNaN( floatx80 a )
{
commonNaNT z;
 
if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
z.sign = a.high>>15;
z.low = 0;
z.high = a.low<<1;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the extended
| double-precision floating-point format.
*----------------------------------------------------------------------------*/
 
static floatx80 commonNaNToFloatx80( commonNaNT a )
{
floatx80 z;
 
z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Takes two extended double-precision floating-point values `a' and `b', one
| of which is a NaN, and returns the appropriate NaN result. If either `a' or
| `b' is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
 
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
{
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
 
aIsNaN = floatx80_is_nan( a );
aIsSignalingNaN = floatx80_is_signaling_nan( a );
bIsNaN = floatx80_is_nan( b );
bIsSignalingNaN = floatx80_is_signaling_nan( b );
a.low |= LIT64( 0xC000000000000000 );
b.low |= LIT64( 0xC000000000000000 );
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
if ( aIsSignalingNaN ) {
if ( bIsSignalingNaN ) goto returnLargerSignificand;
return bIsNaN ? b : a;
}
else if ( aIsNaN ) {
if ( bIsSignalingNaN | ! bIsNaN ) return a;
returnLargerSignificand:
if ( a.low < b.low ) return b;
if ( b.low < a.low ) return a;
return ( a.high < b.high ) ? a : b;
}
else {
return b;
}
 
}
 
#endif
 
#ifdef FLOAT128
 
/*----------------------------------------------------------------------------
| The pattern for a default generated quadruple-precision NaN. The `high' and
| `low' values hold the most- and least-significant bits, respectively.
*----------------------------------------------------------------------------*/
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
#define float128_default_nan_low LIT64( 0x0000000000000000 )
 
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
| otherwise returns 0.
*----------------------------------------------------------------------------*/
 
flag float128_is_nan( float128 a )
{
 
return
( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
&& ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is a
| signaling NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/
 
flag float128_is_signaling_nan( float128 a )
{
 
return
( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
&& ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point NaN
| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
 
static commonNaNT float128ToCommonNaN( float128 a )
{
commonNaNT z;
 
if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
z.sign = a.high>>63;
shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the quadruple-
| precision floating-point format.
*----------------------------------------------------------------------------*/
 
static float128 commonNaNToFloat128( commonNaNT a )
{
float128 z;
 
shift128Right( a.high, a.low, 16, &z.high, &z.low );
z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
return z;
 
}
 
/*----------------------------------------------------------------------------
| Takes two quadruple-precision floating-point values `a' and `b', one of
| which is a NaN, and returns the appropriate NaN result. If either `a' or
| `b' is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
 
static float128 propagateFloat128NaN( float128 a, float128 b )
{
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
 
aIsNaN = float128_is_nan( a );
aIsSignalingNaN = float128_is_signaling_nan( a );
bIsNaN = float128_is_nan( b );
bIsSignalingNaN = float128_is_signaling_nan( b );
a.high |= LIT64( 0x0000800000000000 );
b.high |= LIT64( 0x0000800000000000 );
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
if ( aIsSignalingNaN ) {
if ( bIsSignalingNaN ) goto returnLargerSignificand;
return bIsNaN ? b : a;
}
else if ( aIsNaN ) {
if ( bIsSignalingNaN | ! bIsNaN ) return a;
returnLargerSignificand:
if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
return ( a.high < b.high ) ? a : b;
}
else {
return b;
}
 
}
 
#endif
 
 
 
/*----------------------------------------------------------------------------
| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
| and 7, and returns the properly rounded 32-bit integer corresponding to the
| input. If `zSign' is 1, the input is negated before being converted to an
| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input
| is simply rounded to an integer, with the inexact exception raised if the
| input cannot be represented exactly as an integer. However, if the fixed-
| point input is too large, the invalid exception is raised and the largest
| positive or negative integer is returned.
*----------------------------------------------------------------------------*/
 
static int32 roundAndPackInt32( flag zSign, bits64 absZ )
{
int8 roundingMode;
flag roundNearestEven;
int8 roundIncrement, roundBits;
int32 z;
 
roundingMode = float_rounding_mode;
roundNearestEven = ( roundingMode == float_round_nearest_even );
roundIncrement = 0x40;
if ( ! roundNearestEven ) {
if ( roundingMode == float_round_to_zero ) {
roundIncrement = 0;
}
else {
roundIncrement = 0x7F;
if ( zSign ) {
if ( roundingMode == float_round_up ) roundIncrement = 0;
}
else {
if ( roundingMode == float_round_down ) roundIncrement = 0;
}
}
}
roundBits = absZ & 0x7F;
absZ = ( absZ + roundIncrement )>>7;
absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
z = absZ;
if ( zSign ) z = - z;
if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
float_raise( float_flag_invalid );
return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
}
if ( roundBits ) float_exception_flags |= float_flag_inexact;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
| `absZ1', with binary point between bits 63 and 64 (between the input words),
| and returns the properly rounded 64-bit integer corresponding to the input.
| If `zSign' is 1, the input is negated before being converted to an integer.
| Ordinarily, the fixed-point input is simply rounded to an integer, with
| the inexact exception raised if the input cannot be represented exactly as
| an integer. However, if the fixed-point input is too large, the invalid
| exception is raised and the largest positive or negative integer is
| returned.
*----------------------------------------------------------------------------*/
 
static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 )
{
int8 roundingMode;
flag roundNearestEven, increment;
int64 z;
 
roundingMode = float_rounding_mode;
roundNearestEven = ( roundingMode == float_round_nearest_even );
increment = ( (sbits64) absZ1 < 0 );
if ( ! roundNearestEven ) {
if ( roundingMode == float_round_to_zero ) {
increment = 0;
}
else {
if ( zSign ) {
increment = ( roundingMode == float_round_down ) && absZ1;
}
else {
increment = ( roundingMode == float_round_up ) && absZ1;
}
}
}
if ( increment ) {
++absZ0;
if ( absZ0 == 0 ) goto overflow;
absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven );
}
z = absZ0;
if ( zSign ) z = - z;
if ( z && ( ( z < 0 ) ^ zSign ) ) {
overflow:
float_raise( float_flag_invalid );
return
zSign ? (sbits64) LIT64( 0x8000000000000000 )
: LIT64( 0x7FFFFFFFFFFFFFFF );
}
if ( absZ1 ) float_exception_flags |= float_flag_inexact;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the fraction bits of the single-precision floating-point value `a'.
*----------------------------------------------------------------------------*/
 
INLINE bits32 extractFloat32Frac( float32 a )
{
 
return a & 0x007FFFFF;
 
}
 
/*----------------------------------------------------------------------------
| Returns the exponent bits of the single-precision floating-point value `a'.
*----------------------------------------------------------------------------*/
 
INLINE int16 extractFloat32Exp( float32 a )
{
 
return ( a>>23 ) & 0xFF;
 
}
 
/*----------------------------------------------------------------------------
| Returns the sign bit of the single-precision floating-point value `a'.
*----------------------------------------------------------------------------*/
 
INLINE flag extractFloat32Sign( float32 a )
{
 
return a>>31;
 
}
 
/*----------------------------------------------------------------------------
| Normalizes the subnormal single-precision floating-point value represented
| by the denormalized significand `aSig'. The normalized exponent and
| significand are stored at the locations pointed to by `zExpPtr' and
| `zSigPtr', respectively.
*----------------------------------------------------------------------------*/
 
static void
normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
{
int8 shiftCount;
 
shiftCount = countLeadingZeros32( aSig ) - 8;
*zSigPtr = aSig<<shiftCount;
*zExpPtr = 1 - shiftCount;
 
}
 
/*----------------------------------------------------------------------------
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
| single-precision floating-point value, returning the result. After being
| shifted into the proper positions, the three fields are simply added
| together to form the result. This means that any integer portion of `zSig'
| will be added into the exponent. Since a properly normalized significand
| will have an integer portion equal to 1, the `zExp' input should be 1 less
| than the desired result exponent whenever `zSig' is a complete, normalized
| significand.
*----------------------------------------------------------------------------*/
 
INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
{
 
return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
 
}
 
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and significand `zSig', and returns the proper single-precision floating-
| point value corresponding to the abstract input. Ordinarily, the abstract
| value is simply rounded and packed into the single-precision format, with
| the inexact exception raised if the abstract input cannot be represented
| exactly. However, if the abstract value is too large, the overflow and
| inexact exceptions are raised and an infinity or maximal finite value is
| returned. If the abstract value is too small, the input value is rounded to
| a subnormal number, and the underflow and inexact exceptions are raised if
| the abstract input cannot be represented exactly as a subnormal single-
| precision floating-point number.
| The input significand `zSig' has its binary point between bits 30
| and 29, which is 7 bits to the left of the usual location. This shifted
| significand must be normalized or smaller. If `zSig' is not normalized,
| `zExp' must be 0; in that case, the result returned is a subnormal number,
| and it must not require rounding. In the usual case that `zSig' is
| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
| The handling of underflow and overflow follows the IEC/IEEE Standard for
| Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
{
int8 roundingMode;
flag roundNearestEven;
int8 roundIncrement, roundBits;
flag isTiny;
 
roundingMode = float_rounding_mode;
roundNearestEven = ( roundingMode == float_round_nearest_even );
roundIncrement = 0x40;
if ( ! roundNearestEven ) {
if ( roundingMode == float_round_to_zero ) {
roundIncrement = 0;
}
else {
roundIncrement = 0x7F;
if ( zSign ) {
if ( roundingMode == float_round_up ) roundIncrement = 0;
}
else {
if ( roundingMode == float_round_down ) roundIncrement = 0;
}
}
}
roundBits = zSig & 0x7F;
if ( 0xFD <= (bits16) zExp ) {
if ( ( 0xFD < zExp )
|| ( ( zExp == 0xFD )
&& ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
) {
float_raise( float_flag_overflow | float_flag_inexact );
return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
}
if ( zExp < 0 ) {
isTiny =
( float_detect_tininess == float_tininess_before_rounding )
|| ( zExp < -1 )
|| ( zSig + roundIncrement < 0x80000000 );
shift32RightJamming( zSig, - zExp, &zSig );
zExp = 0;
roundBits = zSig & 0x7F;
if ( isTiny && roundBits ) float_raise( float_flag_underflow );
}
}
if ( roundBits ) float_exception_flags |= float_flag_inexact;
zSig = ( zSig + roundIncrement )>>7;
zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
if ( zSig == 0 ) zExp = 0;
return packFloat32( zSign, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and significand `zSig', and returns the proper single-precision floating-
| point value corresponding to the abstract input. This routine is just like
| `roundAndPackFloat32' except that `zSig' does not have to be normalized.
| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
| floating-point exponent.
*----------------------------------------------------------------------------*/
 
static float32
normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
{
int8 shiftCount;
 
shiftCount = countLeadingZeros32( zSig ) - 1;
return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
 
}
 
/*----------------------------------------------------------------------------
| Returns the fraction bits of the double-precision floating-point value `a'.
*----------------------------------------------------------------------------*/
 
INLINE bits64 extractFloat64Frac( float64 a )
{
 
return a & LIT64( 0x000FFFFFFFFFFFFF );
 
}
 
/*----------------------------------------------------------------------------
| Returns the exponent bits of the double-precision floating-point value `a'.
*----------------------------------------------------------------------------*/
 
INLINE int16 extractFloat64Exp( float64 a )
{
 
return ( a>>52 ) & 0x7FF;
 
}
 
/*----------------------------------------------------------------------------
| Returns the sign bit of the double-precision floating-point value `a'.
*----------------------------------------------------------------------------*/
 
INLINE flag extractFloat64Sign( float64 a )
{
 
return a>>63;
 
}
 
/*----------------------------------------------------------------------------
| Normalizes the subnormal double-precision floating-point value represented
| by the denormalized significand `aSig'. The normalized exponent and
| significand are stored at the locations pointed to by `zExpPtr' and
| `zSigPtr', respectively.
*----------------------------------------------------------------------------*/
 
static void
normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr )
{
int8 shiftCount;
 
shiftCount = countLeadingZeros64( aSig ) - 11;
*zSigPtr = aSig<<shiftCount;
*zExpPtr = 1 - shiftCount;
 
}
 
/*----------------------------------------------------------------------------
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
| double-precision floating-point value, returning the result. After being
| shifted into the proper positions, the three fields are simply added
| together to form the result. This means that any integer portion of `zSig'
| will be added into the exponent. Since a properly normalized significand
| will have an integer portion equal to 1, the `zExp' input should be 1 less
| than the desired result exponent whenever `zSig' is a complete, normalized
| significand.
*----------------------------------------------------------------------------*/
 
INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )
{
 
return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;
 
}
 
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and significand `zSig', and returns the proper double-precision floating-
| point value corresponding to the abstract input. Ordinarily, the abstract
| value is simply rounded and packed into the double-precision format, with
| the inexact exception raised if the abstract input cannot be represented
| exactly. However, if the abstract value is too large, the overflow and
| inexact exceptions are raised and an infinity or maximal finite value is
| returned. If the abstract value is too small, the input value is rounded
| to a subnormal number, and the underflow and inexact exceptions are raised
| if the abstract input cannot be represented exactly as a subnormal double-
| precision floating-point number.
| The input significand `zSig' has its binary point between bits 62
| and 61, which is 10 bits to the left of the usual location. This shifted
| significand must be normalized or smaller. If `zSig' is not normalized,
| `zExp' must be 0; in that case, the result returned is a subnormal number,
| and it must not require rounding. In the usual case that `zSig' is
| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
| The handling of underflow and overflow follows the IEC/IEEE Standard for
| Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
{
int8 roundingMode;
flag roundNearestEven;
int16 roundIncrement, roundBits;
flag isTiny;
 
roundingMode = float_rounding_mode;
roundNearestEven = ( roundingMode == float_round_nearest_even );
roundIncrement = 0x200;
if ( ! roundNearestEven ) {
if ( roundingMode == float_round_to_zero ) {
roundIncrement = 0;
}
else {
roundIncrement = 0x3FF;
if ( zSign ) {
if ( roundingMode == float_round_up ) roundIncrement = 0;
}
else {
if ( roundingMode == float_round_down ) roundIncrement = 0;
}
}
}
roundBits = zSig & 0x3FF;
if ( 0x7FD <= (bits16) zExp ) {
if ( ( 0x7FD < zExp )
|| ( ( zExp == 0x7FD )
&& ( (sbits64) ( zSig + roundIncrement ) < 0 ) )
) {
float_raise( float_flag_overflow | float_flag_inexact );
return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
}
if ( zExp < 0 ) {
isTiny =
( float_detect_tininess == float_tininess_before_rounding )
|| ( zExp < -1 )
|| ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
shift64RightJamming( zSig, - zExp, &zSig );
zExp = 0;
roundBits = zSig & 0x3FF;
if ( isTiny && roundBits ) float_raise( float_flag_underflow );
}
}
if ( roundBits ) float_exception_flags |= float_flag_inexact;
zSig = ( zSig + roundIncrement )>>10;
zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
if ( zSig == 0 ) zExp = 0;
return packFloat64( zSign, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and significand `zSig', and returns the proper double-precision floating-
| point value corresponding to the abstract input. This routine is just like
| `roundAndPackFloat64' except that `zSig' does not have to be normalized.
| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
| floating-point exponent.
*----------------------------------------------------------------------------*/
 
static float64
normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
{
int8 shiftCount;
 
shiftCount = countLeadingZeros64( zSig ) - 1;
return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount );
 
}
 
#ifdef FLOATX80
 
/*----------------------------------------------------------------------------
| Returns the fraction bits of the extended double-precision floating-point
| value `a'.
*----------------------------------------------------------------------------*/
 
INLINE bits64 extractFloatx80Frac( floatx80 a )
{
 
return a.low;
 
}
 
/*----------------------------------------------------------------------------
| Returns the exponent bits of the extended double-precision floating-point
| value `a'.
*----------------------------------------------------------------------------*/
 
INLINE int32 extractFloatx80Exp( floatx80 a )
{
 
return a.high & 0x7FFF;
 
}
 
/*----------------------------------------------------------------------------
| Returns the sign bit of the extended double-precision floating-point value
| `a'.
*----------------------------------------------------------------------------*/
 
INLINE flag extractFloatx80Sign( floatx80 a )
{
 
return a.high>>15;
 
}
 
/*----------------------------------------------------------------------------
| Normalizes the subnormal extended double-precision floating-point value
| represented by the denormalized significand `aSig'. The normalized exponent
| and significand are stored at the locations pointed to by `zExpPtr' and
| `zSigPtr', respectively.
*----------------------------------------------------------------------------*/
 
static void
normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr )
{
int8 shiftCount;
 
shiftCount = countLeadingZeros64( aSig );
*zSigPtr = aSig<<shiftCount;
*zExpPtr = 1 - shiftCount;
 
}
 
/*----------------------------------------------------------------------------
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
| extended double-precision floating-point value, returning the result.
*----------------------------------------------------------------------------*/
 
INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
{
floatx80 z;
 
z.low = zSig;
z.high = ( ( (bits16) zSign )<<15 ) + zExp;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
| and returns the proper extended double-precision floating-point value
| corresponding to the abstract input. Ordinarily, the abstract value is
| rounded and packed into the extended double-precision format, with the
| inexact exception raised if the abstract input cannot be represented
| exactly. However, if the abstract value is too large, the overflow and
| inexact exceptions are raised and an infinity or maximal finite value is
| returned. If the abstract value is too small, the input value is rounded to
| a subnormal number, and the underflow and inexact exceptions are raised if
| the abstract input cannot be represented exactly as a subnormal extended
| double-precision floating-point number.
| If `roundingPrecision' is 32 or 64, the result is rounded to the same
| number of bits as single or double precision, respectively. Otherwise, the
| result is rounded to the full precision of the extended double-precision
| format.
| The input significand must be normalized or smaller. If the input
| significand is not normalized, `zExp' must be 0; in that case, the result
| returned is a subnormal number, and it must not require rounding. The
| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static floatx80
roundAndPackFloatx80(
int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
)
{
int8 roundingMode;
flag roundNearestEven, increment, isTiny;
int64 roundIncrement, roundMask, roundBits;
 
roundingMode = float_rounding_mode;
roundNearestEven = ( roundingMode == float_round_nearest_even );
if ( roundingPrecision == 80 ) goto precision80;
if ( roundingPrecision == 64 ) {
roundIncrement = LIT64( 0x0000000000000400 );
roundMask = LIT64( 0x00000000000007FF );
}
else if ( roundingPrecision == 32 ) {
roundIncrement = LIT64( 0x0000008000000000 );
roundMask = LIT64( 0x000000FFFFFFFFFF );
}
else {
goto precision80;
}
zSig0 |= ( zSig1 != 0 );
if ( ! roundNearestEven ) {
if ( roundingMode == float_round_to_zero ) {
roundIncrement = 0;
}
else {
roundIncrement = roundMask;
if ( zSign ) {
if ( roundingMode == float_round_up ) roundIncrement = 0;
}
else {
if ( roundingMode == float_round_down ) roundIncrement = 0;
}
}
}
roundBits = zSig0 & roundMask;
if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
if ( ( 0x7FFE < zExp )
|| ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
) {
goto overflow;
}
if ( zExp <= 0 ) {
isTiny =
( float_detect_tininess == float_tininess_before_rounding )
|| ( zExp < 0 )
|| ( zSig0 <= zSig0 + roundIncrement );
shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
zExp = 0;
roundBits = zSig0 & roundMask;
if ( isTiny && roundBits ) float_raise( float_flag_underflow );
if ( roundBits ) float_exception_flags |= float_flag_inexact;
zSig0 += roundIncrement;
if ( (sbits64) zSig0 < 0 ) zExp = 1;
roundIncrement = roundMask + 1;
if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
roundMask |= roundIncrement;
}
zSig0 &= ~ roundMask;
return packFloatx80( zSign, zExp, zSig0 );
}
}
if ( roundBits ) float_exception_flags |= float_flag_inexact;
zSig0 += roundIncrement;
if ( zSig0 < roundIncrement ) {
++zExp;
zSig0 = LIT64( 0x8000000000000000 );
}
roundIncrement = roundMask + 1;
if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
roundMask |= roundIncrement;
}
zSig0 &= ~ roundMask;
if ( zSig0 == 0 ) zExp = 0;
return packFloatx80( zSign, zExp, zSig0 );
precision80:
increment = ( (sbits64) zSig1 < 0 );
if ( ! roundNearestEven ) {
if ( roundingMode == float_round_to_zero ) {
increment = 0;
}
else {
if ( zSign ) {
increment = ( roundingMode == float_round_down ) && zSig1;
}
else {
increment = ( roundingMode == float_round_up ) && zSig1;
}
}
}
if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
if ( ( 0x7FFE < zExp )
|| ( ( zExp == 0x7FFE )
&& ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
&& increment
)
) {
roundMask = 0;
overflow:
float_raise( float_flag_overflow | float_flag_inexact );
if ( ( roundingMode == float_round_to_zero )
|| ( zSign && ( roundingMode == float_round_up ) )
|| ( ! zSign && ( roundingMode == float_round_down ) )
) {
return packFloatx80( zSign, 0x7FFE, ~ roundMask );
}
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
if ( zExp <= 0 ) {
isTiny =
( float_detect_tininess == float_tininess_before_rounding )
|| ( zExp < 0 )
|| ! increment
|| ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
zExp = 0;
if ( isTiny && zSig1 ) float_raise( float_flag_underflow );
if ( zSig1 ) float_exception_flags |= float_flag_inexact;
if ( roundNearestEven ) {
increment = ( (sbits64) zSig1 < 0 );
}
else {
if ( zSign ) {
increment = ( roundingMode == float_round_down ) && zSig1;
}
else {
increment = ( roundingMode == float_round_up ) && zSig1;
}
}
if ( increment ) {
++zSig0;
zSig0 &=
~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven );
if ( (sbits64) zSig0 < 0 ) zExp = 1;
}
return packFloatx80( zSign, zExp, zSig0 );
}
}
if ( zSig1 ) float_exception_flags |= float_flag_inexact;
if ( increment ) {
++zSig0;
if ( zSig0 == 0 ) {
++zExp;
zSig0 = LIT64( 0x8000000000000000 );
}
else {
zSig0 &= ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven );
}
}
else {
if ( zSig0 == 0 ) zExp = 0;
}
return packFloatx80( zSign, zExp, zSig0 );
 
}
 
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent
| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
| and returns the proper extended double-precision floating-point value
| corresponding to the abstract input. This routine is just like
| `roundAndPackFloatx80' except that the input significand does not have to be
| normalized.
*----------------------------------------------------------------------------*/
 
static floatx80
normalizeRoundAndPackFloatx80(
int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
)
{
int8 shiftCount;
 
if ( zSig0 == 0 ) {
zSig0 = zSig1;
zSig1 = 0;
zExp -= 64;
}
shiftCount = countLeadingZeros64( zSig0 );
shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
zExp -= shiftCount;
return
roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 );
 
}
 
#endif
 
#ifdef FLOAT128
 
/*----------------------------------------------------------------------------
| Returns the least-significant 64 fraction bits of the quadruple-precision
| floating-point value `a'.
*----------------------------------------------------------------------------*/
 
INLINE bits64 extractFloat128Frac1( float128 a )
{
 
return a.low;
 
}
 
/*----------------------------------------------------------------------------
| Returns the most-significant 48 fraction bits of the quadruple-precision
| floating-point value `a'.
*----------------------------------------------------------------------------*/
 
INLINE bits64 extractFloat128Frac0( float128 a )
{
 
return a.high & LIT64( 0x0000FFFFFFFFFFFF );
 
}
 
/*----------------------------------------------------------------------------
| Returns the exponent bits of the quadruple-precision floating-point value
| `a'.
*----------------------------------------------------------------------------*/
 
INLINE int32 extractFloat128Exp( float128 a )
{
 
return ( a.high>>48 ) & 0x7FFF;
 
}
 
/*----------------------------------------------------------------------------
| Returns the sign bit of the quadruple-precision floating-point value `a'.
*----------------------------------------------------------------------------*/
 
INLINE flag extractFloat128Sign( float128 a )
{
 
return a.high>>63;
 
}
 
/*----------------------------------------------------------------------------
| Normalizes the subnormal quadruple-precision floating-point value
| represented by the denormalized significand formed by the concatenation of
| `aSig0' and `aSig1'. The normalized exponent is stored at the location
| pointed to by `zExpPtr'. The most significant 49 bits of the normalized
| significand are stored at the location pointed to by `zSig0Ptr', and the
| least significant 64 bits of the normalized significand are stored at the
| location pointed to by `zSig1Ptr'.
*----------------------------------------------------------------------------*/
 
static void
normalizeFloat128Subnormal(
bits64 aSig0,
bits64 aSig1,
int32 *zExpPtr,
bits64 *zSig0Ptr,
bits64 *zSig1Ptr
)
{
int8 shiftCount;
 
if ( aSig0 == 0 ) {
shiftCount = countLeadingZeros64( aSig1 ) - 15;
if ( shiftCount < 0 ) {
*zSig0Ptr = aSig1>>( - shiftCount );
*zSig1Ptr = aSig1<<( shiftCount & 63 );
}
else {
*zSig0Ptr = aSig1<<shiftCount;
*zSig1Ptr = 0;
}
*zExpPtr = - shiftCount - 63;
}
else {
shiftCount = countLeadingZeros64( aSig0 ) - 15;
shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
*zExpPtr = 1 - shiftCount;
}
 
}
 
/*----------------------------------------------------------------------------
| Packs the sign `zSign', the exponent `zExp', and the significand formed
| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
| floating-point value, returning the result. After being shifted into the
| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
| added together to form the most significant 32 bits of the result. This
| means that any integer portion of `zSig0' will be added into the exponent.
| Since a properly normalized significand will have an integer portion equal
| to 1, the `zExp' input should be 1 less than the desired result exponent
| whenever `zSig0' and `zSig1' concatenated form a complete, normalized
| significand.
*----------------------------------------------------------------------------*/
 
INLINE float128
packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
{
float128 z;
 
z.low = zSig1;
z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and extended significand formed by the concatenation of `zSig0', `zSig1',
| and `zSig2', and returns the proper quadruple-precision floating-point value
| corresponding to the abstract input. Ordinarily, the abstract value is
| simply rounded and packed into the quadruple-precision format, with the
| inexact exception raised if the abstract input cannot be represented
| exactly. However, if the abstract value is too large, the overflow and
| inexact exceptions are raised and an infinity or maximal finite value is
| returned. If the abstract value is too small, the input value is rounded to
| a subnormal number, and the underflow and inexact exceptions are raised if
| the abstract input cannot be represented exactly as a subnormal quadruple-
| precision floating-point number.
| The input significand must be normalized or smaller. If the input
| significand is not normalized, `zExp' must be 0; in that case, the result
| returned is a subnormal number, and it must not require rounding. In the
| usual case that the input significand is normalized, `zExp' must be 1 less
| than the ``true'' floating-point exponent. The handling of underflow and
| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static float128
roundAndPackFloat128(
flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 )
{
int8 roundingMode;
flag roundNearestEven, increment, isTiny;
 
roundingMode = float_rounding_mode;
roundNearestEven = ( roundingMode == float_round_nearest_even );
increment = ( (sbits64) zSig2 < 0 );
if ( ! roundNearestEven ) {
if ( roundingMode == float_round_to_zero ) {
increment = 0;
}
else {
if ( zSign ) {
increment = ( roundingMode == float_round_down ) && zSig2;
}
else {
increment = ( roundingMode == float_round_up ) && zSig2;
}
}
}
if ( 0x7FFD <= (bits32) zExp ) {
if ( ( 0x7FFD < zExp )
|| ( ( zExp == 0x7FFD )
&& eq128(
LIT64( 0x0001FFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFF ),
zSig0,
zSig1
)
&& increment
)
) {
float_raise( float_flag_overflow | float_flag_inexact );
if ( ( roundingMode == float_round_to_zero )
|| ( zSign && ( roundingMode == float_round_up ) )
|| ( ! zSign && ( roundingMode == float_round_down ) )
) {
return
packFloat128(
zSign,
0x7FFE,
LIT64( 0x0000FFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFF )
);
}
return packFloat128( zSign, 0x7FFF, 0, 0 );
}
if ( zExp < 0 ) {
isTiny =
( float_detect_tininess == float_tininess_before_rounding )
|| ( zExp < -1 )
|| ! increment
|| lt128(
zSig0,
zSig1,
LIT64( 0x0001FFFFFFFFFFFF ),
LIT64( 0xFFFFFFFFFFFFFFFF )
);
shift128ExtraRightJamming(
zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
zExp = 0;
if ( isTiny && zSig2 ) float_raise( float_flag_underflow );
if ( roundNearestEven ) {
increment = ( (sbits64) zSig2 < 0 );
}
else {
if ( zSign ) {
increment = ( roundingMode == float_round_down ) && zSig2;
}
else {
increment = ( roundingMode == float_round_up ) && zSig2;
}
}
}
}
if ( zSig2 ) float_exception_flags |= float_flag_inexact;
if ( increment ) {
add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
}
else {
if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
}
return packFloat128( zSign, zExp, zSig0, zSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and significand formed by the concatenation of `zSig0' and `zSig1', and
| returns the proper quadruple-precision floating-point value corresponding
| to the abstract input. This routine is just like `roundAndPackFloat128'
| except that the input significand has fewer bits and does not have to be
| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
| point exponent.
*----------------------------------------------------------------------------*/
 
static float128
normalizeRoundAndPackFloat128(
flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
{
int8 shiftCount;
bits64 zSig2;
 
if ( zSig0 == 0 ) {
zSig0 = zSig1;
zSig1 = 0;
zExp -= 64;
}
shiftCount = countLeadingZeros64( zSig0 ) - 15;
if ( 0 <= shiftCount ) {
zSig2 = 0;
shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
}
else {
shift128ExtraRightJamming(
zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
}
zExp -= shiftCount;
return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
 
}
 
#endif
 
/*----------------------------------------------------------------------------
| Returns the result of converting the 32-bit two's complement integer `a'
| to the single-precision floating-point format. The conversion is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 int32_to_float32( int32 a )
{
flag zSign;
 
if ( a == 0 ) return 0;
if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
zSign = ( a < 0 );
return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the 32-bit two's complement integer `a'
| to the double-precision floating-point format. The conversion is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 int32_to_float64( int32 a )
{
flag zSign;
uint32 absA;
int8 shiftCount;
bits64 zSig;
 
if ( a == 0 ) return 0;
zSign = ( a < 0 );
absA = zSign ? - a : a;
shiftCount = countLeadingZeros32( absA ) + 21;
zSig = absA;
return packFloat64( zSign, 0x432 - shiftCount, zSig<<shiftCount );
 
}
 
#ifdef FLOATX80
 
/*----------------------------------------------------------------------------
| Returns the result of converting the 32-bit two's complement integer `a'
| to the extended double-precision floating-point format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 int32_to_floatx80( int32 a )
{
flag zSign;
uint32 absA;
int8 shiftCount;
bits64 zSig;
 
if ( a == 0 ) return packFloatx80( 0, 0, 0 );
zSign = ( a < 0 );
absA = zSign ? - a : a;
shiftCount = countLeadingZeros32( absA ) + 32;
zSig = absA;
return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
 
}
 
#endif
 
#ifdef FLOAT128
 
/*----------------------------------------------------------------------------
| Returns the result of converting the 32-bit two's complement integer `a' to
| the quadruple-precision floating-point format. The conversion is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 int32_to_float128( int32 a )
{
flag zSign;
uint32 absA;
int8 shiftCount;
bits64 zSig0;
 
if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
zSign = ( a < 0 );
absA = zSign ? - a : a;
shiftCount = countLeadingZeros32( absA ) + 17;
zSig0 = absA;
return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
 
}
 
#endif
 
/*----------------------------------------------------------------------------
| Returns the result of converting the 64-bit two's complement integer `a'
| to the single-precision floating-point format. The conversion is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 int64_to_float32( int64 a )
{
flag zSign;
uint64 absA;
int8 shiftCount;
//bits32 zSig; // Unused variable
 
if ( a == 0 ) return 0;
zSign = ( a < 0 );
absA = zSign ? - a : a;
shiftCount = countLeadingZeros64( absA ) - 40;
if ( 0 <= shiftCount ) {
return packFloat32( zSign, 0x95 - shiftCount, absA<<shiftCount );
}
else {
shiftCount += 7;
if ( shiftCount < 0 ) {
shift64RightJamming( absA, - shiftCount, &absA );
}
else {
absA <<= shiftCount;
}
return roundAndPackFloat32( zSign, 0x9C - shiftCount, absA );
}
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the 64-bit two's complement integer `a'
| to the double-precision floating-point format. The conversion is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 int64_to_float64( int64 a )
{
flag zSign;
 
if ( a == 0 ) return 0;
if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) {
return packFloat64( 1, 0x43E, 0 );
}
zSign = ( a < 0 );
return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a );
 
}
 
#ifdef FLOATX80
 
/*----------------------------------------------------------------------------
| Returns the result of converting the 64-bit two's complement integer `a'
| to the extended double-precision floating-point format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 int64_to_floatx80( int64 a )
{
flag zSign;
uint64 absA;
int8 shiftCount;
 
if ( a == 0 ) return packFloatx80( 0, 0, 0 );
zSign = ( a < 0 );
absA = zSign ? - a : a;
shiftCount = countLeadingZeros64( absA );
return packFloatx80( zSign, 0x403E - shiftCount, absA<<shiftCount );
 
}
 
#endif
 
#ifdef FLOAT128
 
/*----------------------------------------------------------------------------
| Returns the result of converting the 64-bit two's complement integer `a' to
| the quadruple-precision floating-point format. The conversion is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 int64_to_float128( int64 a )
{
flag zSign;
uint64 absA;
int8 shiftCount;
int32 zExp;
bits64 zSig0, zSig1;
 
if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
zSign = ( a < 0 );
absA = zSign ? - a : a;
shiftCount = countLeadingZeros64( absA ) + 49;
zExp = 0x406E - shiftCount;
if ( 64 <= shiftCount ) {
zSig1 = 0;
zSig0 = absA;
shiftCount -= 64;
}
else {
zSig1 = absA;
zSig0 = 0;
}
shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
return packFloat128( zSign, zExp, zSig0, zSig1 );
 
}
 
#endif
 
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point value
| `a' to the 32-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic---which means in particular that the conversion is rounded
| according to the current rounding mode. If `a' is a NaN, the largest
| positive integer is returned. Otherwise, if the conversion overflows, the
| largest integer with the same sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int32 float32_to_int32( float32 a )
{
flag aSign;
int16 aExp, shiftCount;
bits32 aSig;
bits64 aSig64;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
if ( ( aExp == 0xFF ) && aSig ) aSign = 0;
if ( aExp ) aSig |= 0x00800000;
shiftCount = 0xAF - aExp;
aSig64 = aSig;
aSig64 <<= 32;
if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 );
return roundAndPackInt32( aSign, aSig64 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point value
| `a' to the 32-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic, except that the conversion is always rounded toward zero.
| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
| the conversion overflows, the largest integer with the same sign as `a' is
| returned.
*----------------------------------------------------------------------------*/
 
int32 float32_to_int32_round_to_zero( float32 a )
{
flag aSign;
int16 aExp, shiftCount;
bits32 aSig;
int32 z;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
shiftCount = aExp - 0x9E;
if ( 0 <= shiftCount ) {
if ( a != 0xCF000000 ) {
float_raise( float_flag_invalid );
if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
}
return (sbits32) 0x80000000;
}
else if ( aExp <= 0x7E ) {
if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
return 0;
}
aSig = ( aSig | 0x00800000 )<<8;
z = aSig>>( - shiftCount );
if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
float_exception_flags |= float_flag_inexact;
}
if ( aSign ) z = - z;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point value
| `a' to the 64-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic---which means in particular that the conversion is rounded
| according to the current rounding mode. If `a' is a NaN, the largest
| positive integer is returned. Otherwise, if the conversion overflows, the
| largest integer with the same sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int64 float32_to_int64( float32 a )
{
flag aSign;
int16 aExp, shiftCount;
bits32 aSig;
bits64 aSig64, aSigExtra;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
shiftCount = 0xBE - aExp;
if ( shiftCount < 0 ) {
float_raise( float_flag_invalid );
if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
return LIT64( 0x7FFFFFFFFFFFFFFF );
}
return (sbits64) LIT64( 0x8000000000000000 );
}
if ( aExp ) aSig |= 0x00800000;
aSig64 = aSig;
aSig64 <<= 40;
shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra );
return roundAndPackInt64( aSign, aSig64, aSigExtra );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point value
| `a' to the 64-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic, except that the conversion is always rounded toward zero. If
| `a' is a NaN, the largest positive integer is returned. Otherwise, if the
| conversion overflows, the largest integer with the same sign as `a' is
| returned.
*----------------------------------------------------------------------------*/
 
int64 float32_to_int64_round_to_zero( float32 a )
{
flag aSign;
int16 aExp, shiftCount;
bits32 aSig;
bits64 aSig64;
int64 z;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
shiftCount = aExp - 0xBE;
if ( 0 <= shiftCount ) {
if ( a != 0xDF000000 ) {
float_raise( float_flag_invalid );
if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
return LIT64( 0x7FFFFFFFFFFFFFFF );
}
}
return (sbits64) LIT64( 0x8000000000000000 );
}
else if ( aExp <= 0x7E ) {
if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
return 0;
}
aSig64 = aSig | 0x00800000;
aSig64 <<= 40;
z = aSig64>>( - shiftCount );
if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) {
float_exception_flags |= float_flag_inexact;
}
if ( aSign ) z = - z;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point value
| `a' to the double-precision floating-point format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 float32_to_float64( float32 a )
{
flag aSign;
int16 aExp;
bits32 aSig;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
if ( aExp == 0xFF ) {
if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) );
return packFloat64( aSign, 0x7FF, 0 );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
normalizeFloat32Subnormal( aSig, &aExp, &aSig );
--aExp;
}
return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 );
 
}
 
#ifdef FLOATX80
 
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point value
| `a' to the extended double-precision floating-point format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 float32_to_floatx80( float32 a )
{
flag aSign;
int16 aExp;
bits32 aSig;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
if ( aExp == 0xFF ) {
if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) );
return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
normalizeFloat32Subnormal( aSig, &aExp, &aSig );
}
aSig |= 0x00800000;
return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 );
 
}
 
#endif
 
#ifdef FLOAT128
 
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point value
| `a' to the double-precision floating-point format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 float32_to_float128( float32 a )
{
flag aSign;
int16 aExp;
bits32 aSig;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
if ( aExp == 0xFF ) {
if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) );
return packFloat128( aSign, 0x7FFF, 0, 0 );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
normalizeFloat32Subnormal( aSig, &aExp, &aSig );
--aExp;
}
return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 );
 
}
 
#endif
 
/*----------------------------------------------------------------------------
| Rounds the single-precision floating-point value `a' to an integer, and
| returns the result as a single-precision floating-point value. The
| operation is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 float32_round_to_int( float32 a )
{
flag aSign;
int16 aExp;
bits32 lastBitMask, roundBitsMask;
int8 roundingMode;
float32 z;
 
aExp = extractFloat32Exp( a );
if ( 0x96 <= aExp ) {
if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
return propagateFloat32NaN( a, a );
}
return a;
}
if ( aExp <= 0x7E ) {
if ( (bits32) ( a<<1 ) == 0 ) return a;
float_exception_flags |= float_flag_inexact;
aSign = extractFloat32Sign( a );
switch ( float_rounding_mode ) {
case float_round_nearest_even:
if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
return packFloat32( aSign, 0x7F, 0 );
}
break;
case float_round_down:
return aSign ? 0xBF800000 : 0;
case float_round_up:
return aSign ? 0x80000000 : 0x3F800000;
}
return packFloat32( aSign, 0, 0 );
}
lastBitMask = 1;
lastBitMask <<= 0x96 - aExp;
roundBitsMask = lastBitMask - 1;
z = a;
roundingMode = float_rounding_mode;
if ( roundingMode == float_round_nearest_even ) {
z += lastBitMask>>1;
if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
}
else if ( roundingMode != float_round_to_zero ) {
if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
z += roundBitsMask;
}
}
z &= ~ roundBitsMask;
if ( z != a ) float_exception_flags |= float_flag_inexact;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of adding the absolute values of the single-precision
| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
| before being returned. `zSign' is ignored if the result is a NaN.
| The addition is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
{
int16 aExp, bExp, zExp;
bits32 aSig, bSig, zSig;
int16 expDiff;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
bSig = extractFloat32Frac( b );
bExp = extractFloat32Exp( b );
expDiff = aExp - bExp;
aSig <<= 6;
bSig <<= 6;
if ( 0 < expDiff ) {
if ( aExp == 0xFF ) {
if ( aSig ) return propagateFloat32NaN( a, b );
return a;
}
if ( bExp == 0 ) {
--expDiff;
}
else {
bSig |= 0x20000000;
}
shift32RightJamming( bSig, expDiff, &bSig );
zExp = aExp;
}
else if ( expDiff < 0 ) {
if ( bExp == 0xFF ) {
if ( bSig ) return propagateFloat32NaN( a, b );
return packFloat32( zSign, 0xFF, 0 );
}
if ( aExp == 0 ) {
++expDiff;
}
else {
aSig |= 0x20000000;
}
shift32RightJamming( aSig, - expDiff, &aSig );
zExp = bExp;
}
else {
if ( aExp == 0xFF ) {
if ( aSig | bSig ) return propagateFloat32NaN( a, b );
return a;
}
if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
zSig = 0x40000000 + aSig + bSig;
zExp = aExp;
goto roundAndPack;
}
aSig |= 0x20000000;
zSig = ( aSig + bSig )<<1;
--zExp;
if ( (sbits32) zSig < 0 ) {
zSig = aSig + bSig;
++zExp;
}
roundAndPack:
return roundAndPackFloat32( zSign, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of subtracting the absolute values of the single-
| precision floating-point values `a' and `b'. If `zSign' is 1, the
| difference is negated before being returned. `zSign' is ignored if the
| result is a NaN. The subtraction is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
{
int16 aExp, bExp, zExp;
bits32 aSig, bSig, zSig;
int16 expDiff;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
bSig = extractFloat32Frac( b );
bExp = extractFloat32Exp( b );
expDiff = aExp - bExp;
aSig <<= 7;
bSig <<= 7;
if ( 0 < expDiff ) goto aExpBigger;
if ( expDiff < 0 ) goto bExpBigger;
if ( aExp == 0xFF ) {
if ( aSig | bSig ) return propagateFloat32NaN( a, b );
float_raise( float_flag_invalid );
return float32_default_nan;
}
if ( aExp == 0 ) {
aExp = 1;
bExp = 1;
}
if ( bSig < aSig ) goto aBigger;
if ( aSig < bSig ) goto bBigger;
return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
bExpBigger:
if ( bExp == 0xFF ) {
if ( bSig ) return propagateFloat32NaN( a, b );
return packFloat32( zSign ^ 1, 0xFF, 0 );
}
if ( aExp == 0 ) {
++expDiff;
}
else {
aSig |= 0x40000000;
}
shift32RightJamming( aSig, - expDiff, &aSig );
bSig |= 0x40000000;
bBigger:
zSig = bSig - aSig;
zExp = bExp;
zSign ^= 1;
goto normalizeRoundAndPack;
aExpBigger:
if ( aExp == 0xFF ) {
if ( aSig ) return propagateFloat32NaN( a, b );
return a;
}
if ( bExp == 0 ) {
--expDiff;
}
else {
bSig |= 0x40000000;
}
shift32RightJamming( bSig, expDiff, &bSig );
aSig |= 0x40000000;
aBigger:
zSig = aSig - bSig;
zExp = aExp;
normalizeRoundAndPack:
--zExp;
return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of adding the single-precision floating-point values `a'
| and `b'. The operation is performed according to the IEC/IEEE Standard for
| Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 float32_add( float32 a, float32 b )
{
flag aSign, bSign;
 
aSign = extractFloat32Sign( a );
bSign = extractFloat32Sign( b );
if ( aSign == bSign ) {
return addFloat32Sigs( a, b, aSign );
}
else {
return subFloat32Sigs( a, b, aSign );
}
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of subtracting the single-precision floating-point values
| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
| for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 float32_sub( float32 a, float32 b )
{
flag aSign, bSign;
 
aSign = extractFloat32Sign( a );
bSign = extractFloat32Sign( b );
if ( aSign == bSign ) {
return subFloat32Sigs( a, b, aSign );
}
else {
return addFloat32Sigs( a, b, aSign );
}
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of multiplying the single-precision floating-point values
| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
| for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 float32_mul( float32 a, float32 b )
{
flag aSign, bSign, zSign;
int16 aExp, bExp, zExp;
bits32 aSig, bSig;
bits64 zSig64;
bits32 zSig;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
bSig = extractFloat32Frac( b );
bExp = extractFloat32Exp( b );
bSign = extractFloat32Sign( b );
zSign = aSign ^ bSign;
if ( aExp == 0xFF ) {
if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
return propagateFloat32NaN( a, b );
}
if ( ( bExp | bSig ) == 0 ) {
float_raise( float_flag_invalid );
return float32_default_nan;
}
return packFloat32( zSign, 0xFF, 0 );
}
if ( bExp == 0xFF ) {
if ( bSig ) return propagateFloat32NaN( a, b );
if ( ( aExp | aSig ) == 0 ) {
float_raise( float_flag_invalid );
return float32_default_nan;
}
return packFloat32( zSign, 0xFF, 0 );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
normalizeFloat32Subnormal( aSig, &aExp, &aSig );
}
if ( bExp == 0 ) {
if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
normalizeFloat32Subnormal( bSig, &bExp, &bSig );
}
zExp = aExp + bExp - 0x7F;
aSig = ( aSig | 0x00800000 )<<7;
bSig = ( bSig | 0x00800000 )<<8;
shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 );
zSig = zSig64;
if ( 0 <= (sbits32) ( zSig<<1 ) ) {
zSig <<= 1;
--zExp;
}
return roundAndPackFloat32( zSign, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of dividing the single-precision floating-point value `a'
| by the corresponding value `b'. The operation is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 float32_div( float32 a, float32 b )
{
flag aSign, bSign, zSign;
int16 aExp, bExp, zExp;
bits32 aSig, bSig, zSig;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
bSig = extractFloat32Frac( b );
bExp = extractFloat32Exp( b );
bSign = extractFloat32Sign( b );
zSign = aSign ^ bSign;
if ( aExp == 0xFF ) {
if ( aSig ) return propagateFloat32NaN( a, b );
if ( bExp == 0xFF ) {
if ( bSig ) return propagateFloat32NaN( a, b );
float_raise( float_flag_invalid );
return float32_default_nan;
}
return packFloat32( zSign, 0xFF, 0 );
}
if ( bExp == 0xFF ) {
if ( bSig ) return propagateFloat32NaN( a, b );
return packFloat32( zSign, 0, 0 );
}
if ( bExp == 0 ) {
if ( bSig == 0 ) {
if ( ( aExp | aSig ) == 0 ) {
float_raise( float_flag_invalid );
return float32_default_nan;
}
float_raise( float_flag_divbyzero );
return packFloat32( zSign, 0xFF, 0 );
}
normalizeFloat32Subnormal( bSig, &bExp, &bSig );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
normalizeFloat32Subnormal( aSig, &aExp, &aSig );
}
zExp = aExp - bExp + 0x7D;
aSig = ( aSig | 0x00800000 )<<7;
bSig = ( bSig | 0x00800000 )<<8;
if ( bSig <= ( aSig + aSig ) ) {
aSig >>= 1;
++zExp;
}
zSig = ( ( (bits64) aSig )<<32 ) / bSig;
if ( ( zSig & 0x3F ) == 0 ) {
zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 );
}
return roundAndPackFloat32( zSign, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the remainder of the single-precision floating-point value `a'
| with respect to the corresponding value `b'. The operation is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 float32_rem( float32 a, float32 b )
{
flag aSign, bSign, zSign;
int16 aExp, bExp, expDiff;
bits32 aSig, bSig;
bits32 q;
bits64 aSig64, bSig64, q64;
bits32 alternateASig;
sbits32 sigMean;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
bSig = extractFloat32Frac( b );
bExp = extractFloat32Exp( b );
bSign = extractFloat32Sign( b );
if ( aExp == 0xFF ) {
if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
return propagateFloat32NaN( a, b );
}
float_raise( float_flag_invalid );
return float32_default_nan;
}
if ( bExp == 0xFF ) {
if ( bSig ) return propagateFloat32NaN( a, b );
return a;
}
if ( bExp == 0 ) {
if ( bSig == 0 ) {
float_raise( float_flag_invalid );
return float32_default_nan;
}
normalizeFloat32Subnormal( bSig, &bExp, &bSig );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return a;
normalizeFloat32Subnormal( aSig, &aExp, &aSig );
}
expDiff = aExp - bExp;
aSig |= 0x00800000;
bSig |= 0x00800000;
if ( expDiff < 32 ) {
aSig <<= 8;
bSig <<= 8;
if ( expDiff < 0 ) {
if ( expDiff < -1 ) return a;
aSig >>= 1;
}
q = ( bSig <= aSig );
if ( q ) aSig -= bSig;
if ( 0 < expDiff ) {
q = ( ( (bits64) aSig )<<32 ) / bSig;
q >>= 32 - expDiff;
bSig >>= 2;
aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
}
else {
aSig >>= 2;
bSig >>= 2;
}
}
else {
if ( bSig <= aSig ) aSig -= bSig;
aSig64 = ( (bits64) aSig )<<40;
bSig64 = ( (bits64) bSig )<<40;
expDiff -= 64;
while ( 0 < expDiff ) {
q64 = estimateDiv128To64( aSig64, 0, bSig64 );
q64 = ( 2 < q64 ) ? q64 - 2 : 0;
aSig64 = - ( ( bSig * q64 )<<38 );
expDiff -= 62;
}
expDiff += 64;
q64 = estimateDiv128To64( aSig64, 0, bSig64 );
q64 = ( 2 < q64 ) ? q64 - 2 : 0;
q = q64>>( 64 - expDiff );
bSig <<= 6;
aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
}
do {
alternateASig = aSig;
++q;
aSig -= bSig;
} while ( 0 <= (sbits32) aSig );
sigMean = aSig + alternateASig;
if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
aSig = alternateASig;
}
zSign = ( (sbits32) aSig < 0 );
if ( zSign ) aSig = - aSig;
return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the square root of the single-precision floating-point value `a'.
| The operation is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 float32_sqrt( float32 a )
{
flag aSign;
int16 aExp, zExp;
bits32 aSig, zSig;
bits64 rem, term;
 
aSig = extractFloat32Frac( a );
aExp = extractFloat32Exp( a );
aSign = extractFloat32Sign( a );
if ( aExp == 0xFF ) {
if ( aSig ) return propagateFloat32NaN( a, 0 );
if ( ! aSign ) return a;
float_raise( float_flag_invalid );
return float32_default_nan;
}
if ( aSign ) {
if ( ( aExp | aSig ) == 0 ) return a;
float_raise( float_flag_invalid );
return float32_default_nan;
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return 0;
normalizeFloat32Subnormal( aSig, &aExp, &aSig );
}
zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
aSig = ( aSig | 0x00800000 )<<8;
zSig = estimateSqrt32( aExp, aSig ) + 2;
if ( ( zSig & 0x7F ) <= 5 ) {
if ( zSig < 2 ) {
zSig = 0x7FFFFFFF;
goto roundAndPack;
}
aSig >>= aExp & 1;
term = ( (bits64) zSig ) * zSig;
rem = ( ( (bits64) aSig )<<32 ) - term;
while ( (sbits64) rem < 0 ) {
--zSig;
rem += ( ( (bits64) zSig )<<1 ) | 1;
}
zSig |= ( rem != 0 );
}
shift32RightJamming( zSig, 1, &zSig );
roundAndPack:
return roundAndPackFloat32( 0, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is equal to
| the corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float32_eq( float32 a, float32 b )
{
 
if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
|| ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
) {
if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than
| or equal to the corresponding value `b', and 0 otherwise. The comparison
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float32_le( float32 a, float32 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
|| ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
) {
float_raise( float_flag_invalid );
return 0;
}
aSign = extractFloat32Sign( a );
bSign = extractFloat32Sign( b );
if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
return ( a == b ) || ( aSign ^ ( a < b ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float32_lt( float32 a, float32 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
|| ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
) {
float_raise( float_flag_invalid );
return 0;
}
aSign = extractFloat32Sign( a );
bSign = extractFloat32Sign( b );
if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
return ( a != b ) && ( aSign ^ ( a < b ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is equal to
| the corresponding value `b', and 0 otherwise. The invalid exception is
| raised if either operand is a NaN. Otherwise, the comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float32_eq_signaling( float32 a, float32 b )
{
 
if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
|| ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
) {
float_raise( float_flag_invalid );
return 0;
}
return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than or
| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
| cause an exception. Otherwise, the comparison is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float32_le_quiet( float32 a, float32 b )
{
flag aSign, bSign;
//int16 aExp, bExp; // Unused variable
 
if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
|| ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
) {
if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
aSign = extractFloat32Sign( a );
bSign = extractFloat32Sign( b );
if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
return ( a == b ) || ( aSign ^ ( a < b ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
| exception. Otherwise, the comparison is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float32_lt_quiet( float32 a, float32 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
|| ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
) {
if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
aSign = extractFloat32Sign( a );
bSign = extractFloat32Sign( b );
if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
return ( a != b ) && ( aSign ^ ( a < b ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the 32-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic---which means in particular that the conversion is rounded
| according to the current rounding mode. If `a' is a NaN, the largest
| positive integer is returned. Otherwise, if the conversion overflows, the
| largest integer with the same sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int32 float64_to_int32( float64 a )
{
flag aSign;
int16 aExp, shiftCount;
bits64 aSig;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
shiftCount = 0x42C - aExp;
if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
return roundAndPackInt32( aSign, aSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the 32-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic, except that the conversion is always rounded toward zero.
| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
| the conversion overflows, the largest integer with the same sign as `a' is
| returned.
*----------------------------------------------------------------------------*/
 
int32 float64_to_int32_round_to_zero( float64 a )
{
flag aSign;
int16 aExp, shiftCount;
bits64 aSig, savedASig;
int32 z;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
if ( 0x41E < aExp ) {
if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
goto invalid;
}
else if ( aExp < 0x3FF ) {
if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
return 0;
}
aSig |= LIT64( 0x0010000000000000 );
shiftCount = 0x433 - aExp;
savedASig = aSig;
aSig >>= shiftCount;
z = aSig;
if ( aSign ) z = - z;
if ( ( z < 0 ) ^ aSign ) {
invalid:
float_raise( float_flag_invalid );
return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
}
if ( ( aSig<<shiftCount ) != savedASig ) {
float_exception_flags |= float_flag_inexact;
}
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the 64-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic---which means in particular that the conversion is rounded
| according to the current rounding mode. If `a' is a NaN, the largest
| positive integer is returned. Otherwise, if the conversion overflows, the
| largest integer with the same sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int64 float64_to_int64( float64 a )
{
flag aSign;
int16 aExp, shiftCount;
bits64 aSig, aSigExtra;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
shiftCount = 0x433 - aExp;
if ( shiftCount <= 0 ) {
if ( 0x43E < aExp ) {
float_raise( float_flag_invalid );
if ( ! aSign
|| ( ( aExp == 0x7FF )
&& ( aSig != LIT64( 0x0010000000000000 ) ) )
) {
return LIT64( 0x7FFFFFFFFFFFFFFF );
}
return (sbits64) LIT64( 0x8000000000000000 );
}
aSigExtra = 0;
aSig <<= - shiftCount;
}
else {
shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
}
return roundAndPackInt64( aSign, aSig, aSigExtra );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the 64-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic, except that the conversion is always rounded toward zero.
| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
| the conversion overflows, the largest integer with the same sign as `a' is
| returned.
*----------------------------------------------------------------------------*/
 
int64 float64_to_int64_round_to_zero( float64 a )
{
flag aSign;
int16 aExp, shiftCount;
bits64 aSig;
int64 z;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
shiftCount = aExp - 0x433;
if ( 0 <= shiftCount ) {
if ( 0x43E <= aExp ) {
if ( a != LIT64( 0xC3E0000000000000 ) ) {
float_raise( float_flag_invalid );
if ( ! aSign
|| ( ( aExp == 0x7FF )
&& ( aSig != LIT64( 0x0010000000000000 ) ) )
) {
return LIT64( 0x7FFFFFFFFFFFFFFF );
}
}
return (sbits64) LIT64( 0x8000000000000000 );
}
z = aSig<<shiftCount;
}
else {
if ( aExp < 0x3FE ) {
if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
return 0;
}
z = aSig>>( - shiftCount );
if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
float_exception_flags |= float_flag_inexact;
}
}
if ( aSign ) z = - z;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the single-precision floating-point format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 float64_to_float32( float64 a )
{
flag aSign;
int16 aExp;
bits64 aSig;
bits32 zSig;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
if ( aExp == 0x7FF ) {
if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) );
return packFloat32( aSign, 0xFF, 0 );
}
shift64RightJamming( aSig, 22, &aSig );
zSig = aSig;
if ( aExp || zSig ) {
zSig |= 0x40000000;
aExp -= 0x381;
}
return roundAndPackFloat32( aSign, aExp, zSig );
 
}
 
#ifdef FLOATX80
 
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the extended double-precision floating-point format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 float64_to_floatx80( float64 a )
{
flag aSign;
int16 aExp;
bits64 aSig;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
if ( aExp == 0x7FF ) {
if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) );
return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
normalizeFloat64Subnormal( aSig, &aExp, &aSig );
}
return
packFloatx80(
aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
 
}
 
#endif
 
#ifdef FLOAT128
 
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the quadruple-precision floating-point format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 float64_to_float128( float64 a )
{
flag aSign;
int16 aExp;
bits64 aSig, zSig0, zSig1;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
if ( aExp == 0x7FF ) {
if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) );
return packFloat128( aSign, 0x7FFF, 0, 0 );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
normalizeFloat64Subnormal( aSig, &aExp, &aSig );
--aExp;
}
shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
 
}
 
#endif
 
/*----------------------------------------------------------------------------
| Rounds the double-precision floating-point value `a' to an integer, and
| returns the result as a double-precision floating-point value. The
| operation is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 float64_round_to_int( float64 a )
{
flag aSign;
int16 aExp;
bits64 lastBitMask, roundBitsMask;
int8 roundingMode;
float64 z;
 
aExp = extractFloat64Exp( a );
if ( 0x433 <= aExp ) {
if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
return propagateFloat64NaN( a, a );
}
return a;
}
if ( aExp < 0x3FF ) {
if ( (bits64) ( a<<1 ) == 0 ) return a;
float_exception_flags |= float_flag_inexact;
aSign = extractFloat64Sign( a );
switch ( float_rounding_mode ) {
case float_round_nearest_even:
if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
return packFloat64( aSign, 0x3FF, 0 );
}
break;
case float_round_down:
return aSign ? LIT64( 0xBFF0000000000000 ) : 0;
case float_round_up:
return
aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 );
}
return packFloat64( aSign, 0, 0 );
}
lastBitMask = 1;
lastBitMask <<= 0x433 - aExp;
roundBitsMask = lastBitMask - 1;
z = a;
roundingMode = float_rounding_mode;
if ( roundingMode == float_round_nearest_even ) {
z += lastBitMask>>1;
if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
}
else if ( roundingMode != float_round_to_zero ) {
if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) {
z += roundBitsMask;
}
}
z &= ~ roundBitsMask;
if ( z != a ) float_exception_flags |= float_flag_inexact;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of adding the absolute values of the double-precision
| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
| before being returned. `zSign' is ignored if the result is a NaN.
| The addition is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
{
int16 aExp, bExp, zExp;
bits64 aSig, bSig, zSig;
int16 expDiff;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
bSig = extractFloat64Frac( b );
bExp = extractFloat64Exp( b );
expDiff = aExp - bExp;
aSig <<= 9;
bSig <<= 9;
if ( 0 < expDiff ) {
if ( aExp == 0x7FF ) {
if ( aSig ) return propagateFloat64NaN( a, b );
return a;
}
if ( bExp == 0 ) {
--expDiff;
}
else {
bSig |= LIT64( 0x2000000000000000 );
}
shift64RightJamming( bSig, expDiff, &bSig );
zExp = aExp;
}
else if ( expDiff < 0 ) {
if ( bExp == 0x7FF ) {
if ( bSig ) return propagateFloat64NaN( a, b );
return packFloat64( zSign, 0x7FF, 0 );
}
if ( aExp == 0 ) {
++expDiff;
}
else {
aSig |= LIT64( 0x2000000000000000 );
}
shift64RightJamming( aSig, - expDiff, &aSig );
zExp = bExp;
}
else {
if ( aExp == 0x7FF ) {
if ( aSig | bSig ) return propagateFloat64NaN( a, b );
return a;
}
if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
zExp = aExp;
goto roundAndPack;
}
aSig |= LIT64( 0x2000000000000000 );
zSig = ( aSig + bSig )<<1;
--zExp;
if ( (sbits64) zSig < 0 ) {
zSig = aSig + bSig;
++zExp;
}
roundAndPack:
return roundAndPackFloat64( zSign, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of subtracting the absolute values of the double-
| precision floating-point values `a' and `b'. If `zSign' is 1, the
| difference is negated before being returned. `zSign' is ignored if the
| result is a NaN. The subtraction is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
{
int16 aExp, bExp, zExp;
bits64 aSig, bSig, zSig;
int16 expDiff;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
bSig = extractFloat64Frac( b );
bExp = extractFloat64Exp( b );
expDiff = aExp - bExp;
aSig <<= 10;
bSig <<= 10;
if ( 0 < expDiff ) goto aExpBigger;
if ( expDiff < 0 ) goto bExpBigger;
if ( aExp == 0x7FF ) {
if ( aSig | bSig ) return propagateFloat64NaN( a, b );
float_raise( float_flag_invalid );
return float64_default_nan;
}
if ( aExp == 0 ) {
aExp = 1;
bExp = 1;
}
if ( bSig < aSig ) goto aBigger;
if ( aSig < bSig ) goto bBigger;
return packFloat64( float_rounding_mode == float_round_down, 0, 0 );
bExpBigger:
if ( bExp == 0x7FF ) {
if ( bSig ) return propagateFloat64NaN( a, b );
return packFloat64( zSign ^ 1, 0x7FF, 0 );
}
if ( aExp == 0 ) {
++expDiff;
}
else {
aSig |= LIT64( 0x4000000000000000 );
}
shift64RightJamming( aSig, - expDiff, &aSig );
bSig |= LIT64( 0x4000000000000000 );
bBigger:
zSig = bSig - aSig;
zExp = bExp;
zSign ^= 1;
goto normalizeRoundAndPack;
aExpBigger:
if ( aExp == 0x7FF ) {
if ( aSig ) return propagateFloat64NaN( a, b );
return a;
}
if ( bExp == 0 ) {
--expDiff;
}
else {
bSig |= LIT64( 0x4000000000000000 );
}
shift64RightJamming( bSig, expDiff, &bSig );
aSig |= LIT64( 0x4000000000000000 );
aBigger:
zSig = aSig - bSig;
zExp = aExp;
normalizeRoundAndPack:
--zExp;
return normalizeRoundAndPackFloat64( zSign, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of adding the double-precision floating-point values `a'
| and `b'. The operation is performed according to the IEC/IEEE Standard for
| Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 float64_add( float64 a, float64 b )
{
flag aSign, bSign;
 
aSign = extractFloat64Sign( a );
bSign = extractFloat64Sign( b );
if ( aSign == bSign ) {
return addFloat64Sigs( a, b, aSign );
}
else {
return subFloat64Sigs( a, b, aSign );
}
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of subtracting the double-precision floating-point values
| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
| for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 float64_sub( float64 a, float64 b )
{
flag aSign, bSign;
 
aSign = extractFloat64Sign( a );
bSign = extractFloat64Sign( b );
if ( aSign == bSign ) {
return subFloat64Sigs( a, b, aSign );
}
else {
return addFloat64Sigs( a, b, aSign );
}
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of multiplying the double-precision floating-point values
| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
| for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 float64_mul( float64 a, float64 b )
{
flag aSign, bSign, zSign;
int16 aExp, bExp, zExp;
bits64 aSig, bSig, zSig0, zSig1;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
bSig = extractFloat64Frac( b );
bExp = extractFloat64Exp( b );
bSign = extractFloat64Sign( b );
zSign = aSign ^ bSign;
if ( aExp == 0x7FF ) {
if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
return propagateFloat64NaN( a, b );
}
if ( ( bExp | bSig ) == 0 ) {
float_raise( float_flag_invalid );
return float64_default_nan;
}
return packFloat64( zSign, 0x7FF, 0 );
}
if ( bExp == 0x7FF ) {
if ( bSig ) return propagateFloat64NaN( a, b );
if ( ( aExp | aSig ) == 0 ) {
float_raise( float_flag_invalid );
return float64_default_nan;
}
return packFloat64( zSign, 0x7FF, 0 );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
normalizeFloat64Subnormal( aSig, &aExp, &aSig );
}
if ( bExp == 0 ) {
if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
normalizeFloat64Subnormal( bSig, &bExp, &bSig );
}
zExp = aExp + bExp - 0x3FF;
aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
mul64To128( aSig, bSig, &zSig0, &zSig1 );
zSig0 |= ( zSig1 != 0 );
if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
zSig0 <<= 1;
--zExp;
}
return roundAndPackFloat64( zSign, zExp, zSig0 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of dividing the double-precision floating-point value `a'
| by the corresponding value `b'. The operation is performed according to
| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 float64_div( float64 a, float64 b )
{
flag aSign, bSign, zSign;
int16 aExp, bExp, zExp;
bits64 aSig, bSig, zSig;
bits64 rem0, rem1;
bits64 term0, term1;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
bSig = extractFloat64Frac( b );
bExp = extractFloat64Exp( b );
bSign = extractFloat64Sign( b );
zSign = aSign ^ bSign;
if ( aExp == 0x7FF ) {
if ( aSig ) return propagateFloat64NaN( a, b );
if ( bExp == 0x7FF ) {
if ( bSig ) return propagateFloat64NaN( a, b );
float_raise( float_flag_invalid );
return float64_default_nan;
}
return packFloat64( zSign, 0x7FF, 0 );
}
if ( bExp == 0x7FF ) {
if ( bSig ) return propagateFloat64NaN( a, b );
return packFloat64( zSign, 0, 0 );
}
if ( bExp == 0 ) {
if ( bSig == 0 ) {
if ( ( aExp | aSig ) == 0 ) {
float_raise( float_flag_invalid );
return float64_default_nan;
}
float_raise( float_flag_divbyzero );
return packFloat64( zSign, 0x7FF, 0 );
}
normalizeFloat64Subnormal( bSig, &bExp, &bSig );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
normalizeFloat64Subnormal( aSig, &aExp, &aSig );
}
zExp = aExp - bExp + 0x3FD;
aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
if ( bSig <= ( aSig + aSig ) ) {
aSig >>= 1;
++zExp;
}
zSig = estimateDiv128To64( aSig, 0, bSig );
if ( ( zSig & 0x1FF ) <= 2 ) {
mul64To128( bSig, zSig, &term0, &term1 );
sub128( aSig, 0, term0, term1, &rem0, &rem1 );
while ( (sbits64) rem0 < 0 ) {
--zSig;
add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
}
zSig |= ( rem1 != 0 );
}
return roundAndPackFloat64( zSign, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the remainder of the double-precision floating-point value `a'
| with respect to the corresponding value `b'. The operation is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 float64_rem( float64 a, float64 b )
{
flag aSign, bSign, zSign;
int16 aExp, bExp, expDiff;
bits64 aSig, bSig;
bits64 q, alternateASig;
sbits64 sigMean;
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
bSig = extractFloat64Frac( b );
bExp = extractFloat64Exp( b );
bSign = extractFloat64Sign( b );
if ( aExp == 0x7FF ) {
if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
return propagateFloat64NaN( a, b );
}
float_raise( float_flag_invalid );
return float64_default_nan;
}
if ( bExp == 0x7FF ) {
if ( bSig ) return propagateFloat64NaN( a, b );
return a;
}
if ( bExp == 0 ) {
if ( bSig == 0 ) {
float_raise( float_flag_invalid );
return float64_default_nan;
}
normalizeFloat64Subnormal( bSig, &bExp, &bSig );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return a;
normalizeFloat64Subnormal( aSig, &aExp, &aSig );
}
expDiff = aExp - bExp;
aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
if ( expDiff < 0 ) {
if ( expDiff < -1 ) return a;
aSig >>= 1;
}
q = ( bSig <= aSig );
if ( q ) aSig -= bSig;
expDiff -= 64;
while ( 0 < expDiff ) {
q = estimateDiv128To64( aSig, 0, bSig );
q = ( 2 < q ) ? q - 2 : 0;
aSig = - ( ( bSig>>2 ) * q );
expDiff -= 62;
}
expDiff += 64;
if ( 0 < expDiff ) {
q = estimateDiv128To64( aSig, 0, bSig );
q = ( 2 < q ) ? q - 2 : 0;
q >>= 64 - expDiff;
bSig >>= 2;
aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
}
else {
aSig >>= 2;
bSig >>= 2;
}
do {
alternateASig = aSig;
++q;
aSig -= bSig;
} while ( 0 <= (sbits64) aSig );
sigMean = aSig + alternateASig;
if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
aSig = alternateASig;
}
zSign = ( (sbits64) aSig < 0 );
if ( zSign ) aSig = - aSig;
return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the square root of the double-precision floating-point value `a'.
| The operation is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 float64_sqrt( float64 a )
{
flag aSign;
int16 aExp, zExp;
bits64 aSig, zSig, doubleZSig;
bits64 rem0, rem1, term0, term1;
//float64 z; // Unused variable
 
aSig = extractFloat64Frac( a );
aExp = extractFloat64Exp( a );
aSign = extractFloat64Sign( a );
if ( aExp == 0x7FF ) {
if ( aSig ) return propagateFloat64NaN( a, a );
if ( ! aSign ) return a;
float_raise( float_flag_invalid );
return float64_default_nan;
}
if ( aSign ) {
if ( ( aExp | aSig ) == 0 ) return a;
float_raise( float_flag_invalid );
return float64_default_nan;
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return 0;
normalizeFloat64Subnormal( aSig, &aExp, &aSig );
}
zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
aSig |= LIT64( 0x0010000000000000 );
zSig = estimateSqrt32( aExp, aSig>>21 );
aSig <<= 9 - ( aExp & 1 );
zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
if ( ( zSig & 0x1FF ) <= 5 ) {
doubleZSig = zSig<<1;
mul64To128( zSig, zSig, &term0, &term1 );
sub128( aSig, 0, term0, term1, &rem0, &rem1 );
while ( (sbits64) rem0 < 0 ) {
--zSig;
doubleZSig -= 2;
add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 );
}
zSig |= ( ( rem0 | rem1 ) != 0 );
}
return roundAndPackFloat64( 0, zExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is equal to the
| corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float64_eq( float64 a, float64 b )
{
 
if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
|| ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
) {
if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than or
| equal to the corresponding value `b', and 0 otherwise. The comparison is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float64_le( float64 a, float64 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
|| ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
) {
float_raise( float_flag_invalid );
return 0;
}
aSign = extractFloat64Sign( a );
bSign = extractFloat64Sign( b );
if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
return ( a == b ) || ( aSign ^ ( a < b ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float64_lt( float64 a, float64 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
|| ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
) {
float_raise( float_flag_invalid );
return 0;
}
aSign = extractFloat64Sign( a );
bSign = extractFloat64Sign( b );
if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
return ( a != b ) && ( aSign ^ ( a < b ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is equal to the
| corresponding value `b', and 0 otherwise. The invalid exception is raised
| if either operand is a NaN. Otherwise, the comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float64_eq_signaling( float64 a, float64 b )
{
 
if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
|| ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
) {
float_raise( float_flag_invalid );
return 0;
}
return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than or
| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
| cause an exception. Otherwise, the comparison is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float64_le_quiet( float64 a, float64 b )
{
flag aSign, bSign;
//int16 aExp, bExp; // Unused variable
 
if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
|| ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
) {
if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
aSign = extractFloat64Sign( a );
bSign = extractFloat64Sign( b );
if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
return ( a == b ) || ( aSign ^ ( a < b ) );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
| exception. Otherwise, the comparison is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float64_lt_quiet( float64 a, float64 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
|| ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
) {
if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
aSign = extractFloat64Sign( a );
bSign = extractFloat64Sign( b );
if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
return ( a != b ) && ( aSign ^ ( a < b ) );
 
}
 
#ifdef FLOATX80
 
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 32-bit two's complement integer format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic---which means in particular that the conversion
| is rounded according to the current rounding mode. If `a' is a NaN, the
| largest positive integer is returned. Otherwise, if the conversion
| overflows, the largest integer with the same sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int32 floatx80_to_int32( floatx80 a )
{
flag aSign;
int32 aExp, shiftCount;
bits64 aSig;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
shiftCount = 0x4037 - aExp;
if ( shiftCount <= 0 ) shiftCount = 1;
shift64RightJamming( aSig, shiftCount, &aSig );
return roundAndPackInt32( aSign, aSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 32-bit two's complement integer format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic, except that the conversion is always rounded
| toward zero. If `a' is a NaN, the largest positive integer is returned.
| Otherwise, if the conversion overflows, the largest integer with the same
| sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int32 floatx80_to_int32_round_to_zero( floatx80 a )
{
flag aSign;
int32 aExp, shiftCount;
bits64 aSig, savedASig;
int32 z;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
if ( 0x401E < aExp ) {
if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
goto invalid;
}
else if ( aExp < 0x3FFF ) {
if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
return 0;
}
shiftCount = 0x403E - aExp;
savedASig = aSig;
aSig >>= shiftCount;
z = aSig;
if ( aSign ) z = - z;
if ( ( z < 0 ) ^ aSign ) {
invalid:
float_raise( float_flag_invalid );
return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
}
if ( ( aSig<<shiftCount ) != savedASig ) {
float_exception_flags |= float_flag_inexact;
}
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 64-bit two's complement integer format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic---which means in particular that the conversion
| is rounded according to the current rounding mode. If `a' is a NaN,
| the largest positive integer is returned. Otherwise, if the conversion
| overflows, the largest integer with the same sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int64 floatx80_to_int64( floatx80 a )
{
flag aSign;
int32 aExp, shiftCount;
bits64 aSig, aSigExtra;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
shiftCount = 0x403E - aExp;
if ( shiftCount <= 0 ) {
if ( shiftCount ) {
float_raise( float_flag_invalid );
if ( ! aSign
|| ( ( aExp == 0x7FFF )
&& ( aSig != LIT64( 0x8000000000000000 ) ) )
) {
return LIT64( 0x7FFFFFFFFFFFFFFF );
}
return (sbits64) LIT64( 0x8000000000000000 );
}
aSigExtra = 0;
}
else {
shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
}
return roundAndPackInt64( aSign, aSig, aSigExtra );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 64-bit two's complement integer format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic, except that the conversion is always rounded
| toward zero. If `a' is a NaN, the largest positive integer is returned.
| Otherwise, if the conversion overflows, the largest integer with the same
| sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int64 floatx80_to_int64_round_to_zero( floatx80 a )
{
flag aSign;
int32 aExp, shiftCount;
bits64 aSig;
int64 z;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
shiftCount = aExp - 0x403E;
if ( 0 <= shiftCount ) {
aSig &= LIT64( 0x7FFFFFFFFFFFFFFF );
if ( ( a.high != 0xC03E ) || aSig ) {
float_raise( float_flag_invalid );
if ( ! aSign || ( ( aExp == 0x7FFF ) && aSig ) ) {
return LIT64( 0x7FFFFFFFFFFFFFFF );
}
}
return (sbits64) LIT64( 0x8000000000000000 );
}
else if ( aExp < 0x3FFF ) {
if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
return 0;
}
z = aSig>>( - shiftCount );
if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
float_exception_flags |= float_flag_inexact;
}
if ( aSign ) z = - z;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the single-precision floating-point format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 floatx80_to_float32( floatx80 a )
{
flag aSign;
int32 aExp;
bits64 aSig;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 ) ) {
return commonNaNToFloat32( floatx80ToCommonNaN( a ) );
}
return packFloat32( aSign, 0xFF, 0 );
}
shift64RightJamming( aSig, 33, &aSig );
if ( aExp || aSig ) aExp -= 0x3F81;
return roundAndPackFloat32( aSign, aExp, aSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the double-precision floating-point format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 floatx80_to_float64( floatx80 a )
{
flag aSign;
int32 aExp;
bits64 aSig, zSig;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 ) ) {
return commonNaNToFloat64( floatx80ToCommonNaN( a ) );
}
return packFloat64( aSign, 0x7FF, 0 );
}
shift64RightJamming( aSig, 1, &zSig );
if ( aExp || aSig ) aExp -= 0x3C01;
return roundAndPackFloat64( aSign, aExp, zSig );
 
}
 
#ifdef FLOAT128
 
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the quadruple-precision floating-point format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 floatx80_to_float128( floatx80 a )
{
flag aSign;
int16 aExp;
bits64 aSig, zSig0, zSig1;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) {
return commonNaNToFloat128( floatx80ToCommonNaN( a ) );
}
shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
return packFloat128( aSign, aExp, zSig0, zSig1 );
 
}
 
#endif
 
/*----------------------------------------------------------------------------
| Rounds the extended double-precision floating-point value `a' to an integer,
| and returns the result as an extended quadruple-precision floating-point
| value. The operation is performed according to the IEC/IEEE Standard for
| Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 floatx80_round_to_int( floatx80 a )
{
flag aSign;
int32 aExp;
bits64 lastBitMask, roundBitsMask;
int8 roundingMode;
floatx80 z;
 
aExp = extractFloatx80Exp( a );
if ( 0x403E <= aExp ) {
if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
return propagateFloatx80NaN( a, a );
}
return a;
}
if ( aExp < 0x3FFF ) {
if ( ( aExp == 0 )
&& ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
return a;
}
float_exception_flags |= float_flag_inexact;
aSign = extractFloatx80Sign( a );
switch ( float_rounding_mode ) {
case float_round_nearest_even:
if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
) {
return
packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
}
break;
case float_round_down:
return
aSign ?
packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
: packFloatx80( 0, 0, 0 );
case float_round_up:
return
aSign ? packFloatx80( 1, 0, 0 )
: packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
}
return packFloatx80( aSign, 0, 0 );
}
lastBitMask = 1;
lastBitMask <<= 0x403E - aExp;
roundBitsMask = lastBitMask - 1;
z = a;
roundingMode = float_rounding_mode;
if ( roundingMode == float_round_nearest_even ) {
z.low += lastBitMask>>1;
if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
}
else if ( roundingMode != float_round_to_zero ) {
if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
z.low += roundBitsMask;
}
}
z.low &= ~ roundBitsMask;
if ( z.low == 0 ) {
++z.high;
z.low = LIT64( 0x8000000000000000 );
}
if ( z.low != a.low ) float_exception_flags |= float_flag_inexact;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of adding the absolute values of the extended double-
| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is
| negated before being returned. `zSign' is ignored if the result is a NaN.
| The addition is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
{
int32 aExp, bExp, zExp;
bits64 aSig, bSig, zSig0, zSig1;
int32 expDiff;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
bSig = extractFloatx80Frac( b );
bExp = extractFloatx80Exp( b );
expDiff = aExp - bExp;
if ( 0 < expDiff ) {
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
return a;
}
if ( bExp == 0 ) --expDiff;
shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
zExp = aExp;
}
else if ( expDiff < 0 ) {
if ( bExp == 0x7FFF ) {
if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
if ( aExp == 0 ) ++expDiff;
shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
zExp = bExp;
}
else {
if ( aExp == 0x7FFF ) {
if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
return propagateFloatx80NaN( a, b );
}
return a;
}
zSig1 = 0;
zSig0 = aSig + bSig;
if ( aExp == 0 ) {
normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
goto roundAndPack;
}
zExp = aExp;
goto shiftRight1;
}
zSig0 = aSig + bSig;
if ( (sbits64) zSig0 < 0 ) goto roundAndPack;
shiftRight1:
shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
zSig0 |= LIT64( 0x8000000000000000 );
++zExp;
roundAndPack:
return
roundAndPackFloatx80(
floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of subtracting the absolute values of the extended
| double-precision floating-point values `a' and `b'. If `zSign' is 1, the
| difference is negated before being returned. `zSign' is ignored if the
| result is a NaN. The subtraction is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
{
int32 aExp, bExp, zExp;
bits64 aSig, bSig, zSig0, zSig1;
int32 expDiff;
floatx80 z;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
bSig = extractFloatx80Frac( b );
bExp = extractFloatx80Exp( b );
expDiff = aExp - bExp;
if ( 0 < expDiff ) goto aExpBigger;
if ( expDiff < 0 ) goto bExpBigger;
if ( aExp == 0x7FFF ) {
if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
return propagateFloatx80NaN( a, b );
}
float_raise( float_flag_invalid );
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
return z;
}
if ( aExp == 0 ) {
aExp = 1;
bExp = 1;
}
zSig1 = 0;
if ( bSig < aSig ) goto aBigger;
if ( aSig < bSig ) goto bBigger;
return packFloatx80( float_rounding_mode == float_round_down, 0, 0 );
bExpBigger:
if ( bExp == 0x7FFF ) {
if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
if ( aExp == 0 ) ++expDiff;
shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
bBigger:
sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
zExp = bExp;
zSign ^= 1;
goto normalizeRoundAndPack;
aExpBigger:
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
return a;
}
if ( bExp == 0 ) --expDiff;
shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
aBigger:
sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
zExp = aExp;
normalizeRoundAndPack:
return
normalizeRoundAndPackFloatx80(
floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of adding the extended double-precision floating-point
| values `a' and `b'. The operation is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 floatx80_add( floatx80 a, floatx80 b )
{
flag aSign, bSign;
 
aSign = extractFloatx80Sign( a );
bSign = extractFloatx80Sign( b );
if ( aSign == bSign ) {
return addFloatx80Sigs( a, b, aSign );
}
else {
return subFloatx80Sigs( a, b, aSign );
}
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of subtracting the extended double-precision floating-
| point values `a' and `b'. The operation is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 floatx80_sub( floatx80 a, floatx80 b )
{
flag aSign, bSign;
 
aSign = extractFloatx80Sign( a );
bSign = extractFloatx80Sign( b );
if ( aSign == bSign ) {
return subFloatx80Sigs( a, b, aSign );
}
else {
return addFloatx80Sigs( a, b, aSign );
}
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of multiplying the extended double-precision floating-
| point values `a' and `b'. The operation is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 floatx80_mul( floatx80 a, floatx80 b )
{
flag aSign, bSign, zSign;
int32 aExp, bExp, zExp;
bits64 aSig, bSig, zSig0, zSig1;
floatx80 z;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
bSig = extractFloatx80Frac( b );
bExp = extractFloatx80Exp( b );
bSign = extractFloatx80Sign( b );
zSign = aSign ^ bSign;
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 )
|| ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
return propagateFloatx80NaN( a, b );
}
if ( ( bExp | bSig ) == 0 ) goto invalid;
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
if ( bExp == 0x7FFF ) {
if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
if ( ( aExp | aSig ) == 0 ) {
invalid:
float_raise( float_flag_invalid );
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
return z;
}
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
}
if ( bExp == 0 ) {
if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
}
zExp = aExp + bExp - 0x3FFE;
mul64To128( aSig, bSig, &zSig0, &zSig1 );
if ( 0 < (sbits64) zSig0 ) {
shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
--zExp;
}
return
roundAndPackFloatx80(
floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of dividing the extended double-precision floating-point
| value `a' by the corresponding value `b'. The operation is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 floatx80_div( floatx80 a, floatx80 b )
{
flag aSign, bSign, zSign;
int32 aExp, bExp, zExp;
bits64 aSig, bSig, zSig0, zSig1;
bits64 rem0, rem1, rem2, term0, term1, term2;
floatx80 z;
 
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
bSig = extractFloatx80Frac( b );
bExp = extractFloatx80Exp( b );
bSign = extractFloatx80Sign( b );
zSign = aSign ^ bSign;
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
if ( bExp == 0x7FFF ) {
if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
goto invalid;
}
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
if ( bExp == 0x7FFF ) {
if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
return packFloatx80( zSign, 0, 0 );
}
if ( bExp == 0 ) {
if ( bSig == 0 ) {
if ( ( aExp | aSig ) == 0 ) {
invalid:
float_raise( float_flag_invalid );
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
return z;
}
float_raise( float_flag_divbyzero );
return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
}
if ( aExp == 0 ) {
if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
}
zExp = aExp - bExp + 0x3FFE;
rem1 = 0;
if ( bSig <= aSig ) {
shift128Right( aSig, 0, 1, &aSig, &rem1 );
++zExp;
}
zSig0 = estimateDiv128To64( aSig, rem1, bSig );
mul64To128( bSig, zSig0, &term0, &term1 );
sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
while ( (sbits64) rem0 < 0 ) {
--zSig0;
add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
}
zSig1 = estimateDiv128To64( rem1, 0, bSig );
if ( (bits64) ( zSig1<<1 ) <= 8 ) {
mul64To128( bSig, zSig1, &term1, &term2 );
sub128( rem1, 0, term1, term2, &rem1, &rem2 );
while ( (sbits64) rem1 < 0 ) {
--zSig1;
add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
}
zSig1 |= ( ( rem1 | rem2 ) != 0 );
}
return
roundAndPackFloatx80(
floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the remainder of the extended double-precision floating-point value
| `a' with respect to the corresponding value `b'. The operation is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 floatx80_rem( floatx80 a, floatx80 b )
{
flag aSign, bSign, zSign;
int32 aExp, bExp, expDiff;
bits64 aSig0, aSig1, bSig;
bits64 q, term0, term1, alternateASig0, alternateASig1;
floatx80 z;
 
aSig0 = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
bSig = extractFloatx80Frac( b );
bExp = extractFloatx80Exp( b );
bSign = extractFloatx80Sign( b );
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig0<<1 )
|| ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
return propagateFloatx80NaN( a, b );
}
goto invalid;
}
if ( bExp == 0x7FFF ) {
if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
return a;
}
if ( bExp == 0 ) {
if ( bSig == 0 ) {
invalid:
float_raise( float_flag_invalid );
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
return z;
}
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
}
if ( aExp == 0 ) {
if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
}
bSig |= LIT64( 0x8000000000000000 );
zSign = aSign;
expDiff = aExp - bExp;
aSig1 = 0;
if ( expDiff < 0 ) {
if ( expDiff < -1 ) return a;
shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
expDiff = 0;
}
q = ( bSig <= aSig0 );
if ( q ) aSig0 -= bSig;
expDiff -= 64;
while ( 0 < expDiff ) {
q = estimateDiv128To64( aSig0, aSig1, bSig );
q = ( 2 < q ) ? q - 2 : 0;
mul64To128( bSig, q, &term0, &term1 );
sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
expDiff -= 62;
}
expDiff += 64;
if ( 0 < expDiff ) {
q = estimateDiv128To64( aSig0, aSig1, bSig );
q = ( 2 < q ) ? q - 2 : 0;
q >>= 64 - expDiff;
mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
while ( le128( term0, term1, aSig0, aSig1 ) ) {
++q;
sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
}
}
else {
term1 = 0;
term0 = bSig;
}
sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
|| ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
&& ( q & 1 ) )
) {
aSig0 = alternateASig0;
aSig1 = alternateASig1;
zSign = ! zSign;
}
return
normalizeRoundAndPackFloatx80(
80, zSign, bExp + expDiff, aSig0, aSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the square root of the extended double-precision floating-point
| value `a'. The operation is performed according to the IEC/IEEE Standard
| for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 floatx80_sqrt( floatx80 a )
{
flag aSign;
int32 aExp, zExp;
bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0;
bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
floatx80 z;
 
aSig0 = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
if ( aExp == 0x7FFF ) {
if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a );
if ( ! aSign ) return a;
goto invalid;
}
if ( aSign ) {
if ( ( aExp | aSig0 ) == 0 ) return a;
invalid:
float_raise( float_flag_invalid );
z.low = floatx80_default_nan_low;
z.high = floatx80_default_nan_high;
return z;
}
if ( aExp == 0 ) {
if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
}
zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
zSig0 = estimateSqrt32( aExp, aSig0>>32 );
shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
doubleZSig0 = zSig0<<1;
mul64To128( zSig0, zSig0, &term0, &term1 );
sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
while ( (sbits64) rem0 < 0 ) {
--zSig0;
doubleZSig0 -= 2;
add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
}
zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
if ( zSig1 == 0 ) zSig1 = 1;
mul64To128( doubleZSig0, zSig1, &term1, &term2 );
sub128( rem1, 0, term1, term2, &rem1, &rem2 );
mul64To128( zSig1, zSig1, &term2, &term3 );
sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
while ( (sbits64) rem1 < 0 ) {
--zSig1;
shortShift128Left( 0, zSig1, 1, &term2, &term3 );
term3 |= 1;
term2 |= doubleZSig0;
add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
}
zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
}
shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
zSig0 |= doubleZSig0;
return
roundAndPackFloatx80(
floatx80_rounding_precision, 0, zExp, zSig0, zSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is
| equal to the corresponding value `b', and 0 otherwise. The comparison is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
flag floatx80_eq( floatx80 a, floatx80 b )
{
 
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( a )<<1 ) )
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( b )<<1 ) )
) {
if ( floatx80_is_signaling_nan( a )
|| floatx80_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
return
( a.low == b.low )
&& ( ( a.high == b.high )
|| ( ( a.low == 0 )
&& ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
);
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is
| less than or equal to the corresponding value `b', and 0 otherwise. The
| comparison is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag floatx80_le( floatx80 a, floatx80 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( a )<<1 ) )
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( b )<<1 ) )
) {
float_raise( float_flag_invalid );
return 0;
}
aSign = extractFloatx80Sign( a );
bSign = extractFloatx80Sign( b );
if ( aSign != bSign ) {
return
aSign
|| ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
== 0 );
}
return
aSign ? le128( b.high, b.low, a.high, a.low )
: le128( a.high, a.low, b.high, b.low );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is
| less than the corresponding value `b', and 0 otherwise. The comparison
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
flag floatx80_lt( floatx80 a, floatx80 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( a )<<1 ) )
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( b )<<1 ) )
) {
float_raise( float_flag_invalid );
return 0;
}
aSign = extractFloatx80Sign( a );
bSign = extractFloatx80Sign( b );
if ( aSign != bSign ) {
return
aSign
&& ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
!= 0 );
}
return
aSign ? lt128( b.high, b.low, a.high, a.low )
: lt128( a.high, a.low, b.high, b.low );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is equal
| to the corresponding value `b', and 0 otherwise. The invalid exception is
| raised if either operand is a NaN. Otherwise, the comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag floatx80_eq_signaling( floatx80 a, floatx80 b )
{
 
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( a )<<1 ) )
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( b )<<1 ) )
) {
float_raise( float_flag_invalid );
return 0;
}
return
( a.low == b.low )
&& ( ( a.high == b.high )
|| ( ( a.low == 0 )
&& ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
);
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is less
| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs
| do not cause an exception. Otherwise, the comparison is performed according
| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag floatx80_le_quiet( floatx80 a, floatx80 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( a )<<1 ) )
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( b )<<1 ) )
) {
if ( floatx80_is_signaling_nan( a )
|| floatx80_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
aSign = extractFloatx80Sign( a );
bSign = extractFloatx80Sign( b );
if ( aSign != bSign ) {
return
aSign
|| ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
== 0 );
}
return
aSign ? le128( b.high, b.low, a.high, a.low )
: le128( a.high, a.low, b.high, b.low );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is less
| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause
| an exception. Otherwise, the comparison is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag floatx80_lt_quiet( floatx80 a, floatx80 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( a )<<1 ) )
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
&& (bits64) ( extractFloatx80Frac( b )<<1 ) )
) {
if ( floatx80_is_signaling_nan( a )
|| floatx80_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
aSign = extractFloatx80Sign( a );
bSign = extractFloatx80Sign( b );
if ( aSign != bSign ) {
return
aSign
&& ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
!= 0 );
}
return
aSign ? lt128( b.high, b.low, a.high, a.low )
: lt128( a.high, a.low, b.high, b.low );
 
}
 
#endif
 
#ifdef FLOAT128
 
/*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point
| value `a' to the 32-bit two's complement integer format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic---which means in particular that the conversion is rounded
| according to the current rounding mode. If `a' is a NaN, the largest
| positive integer is returned. Otherwise, if the conversion overflows, the
| largest integer with the same sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int32 float128_to_int32( float128 a )
{
flag aSign;
int32 aExp, shiftCount;
bits64 aSig0, aSig1;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
aSig0 |= ( aSig1 != 0 );
shiftCount = 0x4028 - aExp;
if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
return roundAndPackInt32( aSign, aSig0 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point
| value `a' to the 32-bit two's complement integer format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic, except that the conversion is always rounded toward zero. If
| `a' is a NaN, the largest positive integer is returned. Otherwise, if the
| conversion overflows, the largest integer with the same sign as `a' is
| returned.
*----------------------------------------------------------------------------*/
 
int32 float128_to_int32_round_to_zero( float128 a )
{
flag aSign;
int32 aExp, shiftCount;
bits64 aSig0, aSig1, savedASig;
int32 z;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
aSig0 |= ( aSig1 != 0 );
if ( 0x401E < aExp ) {
if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
goto invalid;
}
else if ( aExp < 0x3FFF ) {
if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact;
return 0;
}
aSig0 |= LIT64( 0x0001000000000000 );
shiftCount = 0x402F - aExp;
savedASig = aSig0;
aSig0 >>= shiftCount;
z = aSig0;
if ( aSign ) z = - z;
if ( ( z < 0 ) ^ aSign ) {
invalid:
float_raise( float_flag_invalid );
return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
}
if ( ( aSig0<<shiftCount ) != savedASig ) {
float_exception_flags |= float_flag_inexact;
}
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point
| value `a' to the 64-bit two's complement integer format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic---which means in particular that the conversion is rounded
| according to the current rounding mode. If `a' is a NaN, the largest
| positive integer is returned. Otherwise, if the conversion overflows, the
| largest integer with the same sign as `a' is returned.
*----------------------------------------------------------------------------*/
 
int64 float128_to_int64( float128 a )
{
flag aSign;
int32 aExp, shiftCount;
bits64 aSig0, aSig1;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
shiftCount = 0x402F - aExp;
if ( shiftCount <= 0 ) {
if ( 0x403E < aExp ) {
float_raise( float_flag_invalid );
if ( ! aSign
|| ( ( aExp == 0x7FFF )
&& ( aSig1 || ( aSig0 != LIT64( 0x0001000000000000 ) ) )
)
) {
return LIT64( 0x7FFFFFFFFFFFFFFF );
}
return (sbits64) LIT64( 0x8000000000000000 );
}
shortShift128Left( aSig0, aSig1, - shiftCount, &aSig0, &aSig1 );
}
else {
shift64ExtraRightJamming( aSig0, aSig1, shiftCount, &aSig0, &aSig1 );
}
return roundAndPackInt64( aSign, aSig0, aSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point
| value `a' to the 64-bit two's complement integer format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic, except that the conversion is always rounded toward zero.
| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
| the conversion overflows, the largest integer with the same sign as `a' is
| returned.
*----------------------------------------------------------------------------*/
 
int64 float128_to_int64_round_to_zero( float128 a )
{
flag aSign;
int32 aExp, shiftCount;
bits64 aSig0, aSig1;
int64 z;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
shiftCount = aExp - 0x402F;
if ( 0 < shiftCount ) {
if ( 0x403E <= aExp ) {
aSig0 &= LIT64( 0x0000FFFFFFFFFFFF );
if ( ( a.high == LIT64( 0xC03E000000000000 ) )
&& ( aSig1 < LIT64( 0x0002000000000000 ) ) ) {
if ( aSig1 ) float_exception_flags |= float_flag_inexact;
}
else {
float_raise( float_flag_invalid );
if ( ! aSign || ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) ) {
return LIT64( 0x7FFFFFFFFFFFFFFF );
}
}
return (sbits64) LIT64( 0x8000000000000000 );
}
z = ( aSig0<<shiftCount ) | ( aSig1>>( ( - shiftCount ) & 63 ) );
if ( (bits64) ( aSig1<<shiftCount ) ) {
float_exception_flags |= float_flag_inexact;
}
}
else {
if ( aExp < 0x3FFF ) {
if ( aExp | aSig0 | aSig1 ) {
float_exception_flags |= float_flag_inexact;
}
return 0;
}
z = aSig0>>( - shiftCount );
if ( aSig1
|| ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) {
float_exception_flags |= float_flag_inexact;
}
}
if ( aSign ) z = - z;
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point
| value `a' to the single-precision floating-point format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
float32 float128_to_float32( float128 a )
{
flag aSign;
int32 aExp;
bits64 aSig0, aSig1;
bits32 zSig;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) {
return commonNaNToFloat32( float128ToCommonNaN( a ) );
}
return packFloat32( aSign, 0xFF, 0 );
}
aSig0 |= ( aSig1 != 0 );
shift64RightJamming( aSig0, 18, &aSig0 );
zSig = aSig0;
if ( aExp || zSig ) {
zSig |= 0x40000000;
aExp -= 0x3F81;
}
return roundAndPackFloat32( aSign, aExp, zSig );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point
| value `a' to the double-precision floating-point format. The conversion
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
float64 float128_to_float64( float128 a )
{
flag aSign;
int32 aExp;
bits64 aSig0, aSig1;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) {
return commonNaNToFloat64( float128ToCommonNaN( a ) );
}
return packFloat64( aSign, 0x7FF, 0 );
}
shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
aSig0 |= ( aSig1 != 0 );
if ( aExp || aSig0 ) {
aSig0 |= LIT64( 0x4000000000000000 );
aExp -= 0x3C01;
}
return roundAndPackFloat64( aSign, aExp, aSig0 );
 
}
 
#ifdef FLOATX80
 
/*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point
| value `a' to the extended double-precision floating-point format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
floatx80 float128_to_floatx80( float128 a )
{
flag aSign;
int32 aExp;
bits64 aSig0, aSig1;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) {
return commonNaNToFloatx80( float128ToCommonNaN( a ) );
}
return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
}
if ( aExp == 0 ) {
if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
}
else {
aSig0 |= LIT64( 0x0001000000000000 );
}
shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 );
 
}
 
#endif
 
/*----------------------------------------------------------------------------
| Rounds the quadruple-precision floating-point value `a' to an integer, and
| returns the result as a quadruple-precision floating-point value. The
| operation is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 float128_round_to_int( float128 a )
{
flag aSign;
int32 aExp;
bits64 lastBitMask, roundBitsMask;
int8 roundingMode;
float128 z;
 
aExp = extractFloat128Exp( a );
if ( 0x402F <= aExp ) {
if ( 0x406F <= aExp ) {
if ( ( aExp == 0x7FFF )
&& ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
) {
return propagateFloat128NaN( a, a );
}
return a;
}
lastBitMask = 1;
lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
roundBitsMask = lastBitMask - 1;
z = a;
roundingMode = float_rounding_mode;
if ( roundingMode == float_round_nearest_even ) {
if ( lastBitMask ) {
add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
}
else {
if ( (sbits64) z.low < 0 ) {
++z.high;
if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1;
}
}
}
else if ( roundingMode != float_round_to_zero ) {
if ( extractFloat128Sign( z )
^ ( roundingMode == float_round_up ) ) {
add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
}
}
z.low &= ~ roundBitsMask;
}
else {
if ( aExp < 0x3FFF ) {
if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
float_exception_flags |= float_flag_inexact;
aSign = extractFloat128Sign( a );
switch ( float_rounding_mode ) {
case float_round_nearest_even:
if ( ( aExp == 0x3FFE )
&& ( extractFloat128Frac0( a )
| extractFloat128Frac1( a ) )
) {
return packFloat128( aSign, 0x3FFF, 0, 0 );
}
break;
case float_round_down:
return
aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
: packFloat128( 0, 0, 0, 0 );
case float_round_up:
return
aSign ? packFloat128( 1, 0, 0, 0 )
: packFloat128( 0, 0x3FFF, 0, 0 );
}
return packFloat128( aSign, 0, 0, 0 );
}
lastBitMask = 1;
lastBitMask <<= 0x402F - aExp;
roundBitsMask = lastBitMask - 1;
z.low = 0;
z.high = a.high;
roundingMode = float_rounding_mode;
if ( roundingMode == float_round_nearest_even ) {
z.high += lastBitMask>>1;
if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
z.high &= ~ lastBitMask;
}
}
else if ( roundingMode != float_round_to_zero ) {
if ( extractFloat128Sign( z )
^ ( roundingMode == float_round_up ) ) {
z.high |= ( a.low != 0 );
z.high += roundBitsMask;
}
}
z.high &= ~ roundBitsMask;
}
if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
float_exception_flags |= float_flag_inexact;
}
return z;
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of adding the absolute values of the quadruple-precision
| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
| before being returned. `zSign' is ignored if the result is a NaN.
| The addition is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static float128 addFloat128Sigs( float128 a, float128 b, flag zSign )
{
int32 aExp, bExp, zExp;
bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
int32 expDiff;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
bSig1 = extractFloat128Frac1( b );
bSig0 = extractFloat128Frac0( b );
bExp = extractFloat128Exp( b );
expDiff = aExp - bExp;
if ( 0 < expDiff ) {
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
return a;
}
if ( bExp == 0 ) {
--expDiff;
}
else {
bSig0 |= LIT64( 0x0001000000000000 );
}
shift128ExtraRightJamming(
bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
zExp = aExp;
}
else if ( expDiff < 0 ) {
if ( bExp == 0x7FFF ) {
if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
return packFloat128( zSign, 0x7FFF, 0, 0 );
}
if ( aExp == 0 ) {
++expDiff;
}
else {
aSig0 |= LIT64( 0x0001000000000000 );
}
shift128ExtraRightJamming(
aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
zExp = bExp;
}
else {
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
return propagateFloat128NaN( a, b );
}
return a;
}
add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 );
zSig2 = 0;
zSig0 |= LIT64( 0x0002000000000000 );
zExp = aExp;
goto shiftRight1;
}
aSig0 |= LIT64( 0x0001000000000000 );
add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
--zExp;
if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
++zExp;
shiftRight1:
shift128ExtraRightJamming(
zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
roundAndPack:
return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of subtracting the absolute values of the quadruple-
| precision floating-point values `a' and `b'. If `zSign' is 1, the
| difference is negated before being returned. `zSign' is ignored if the
| result is a NaN. The subtraction is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
static float128 subFloat128Sigs( float128 a, float128 b, flag zSign )
{
int32 aExp, bExp, zExp;
bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
int32 expDiff;
float128 z;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
bSig1 = extractFloat128Frac1( b );
bSig0 = extractFloat128Frac0( b );
bExp = extractFloat128Exp( b );
expDiff = aExp - bExp;
shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
if ( 0 < expDiff ) goto aExpBigger;
if ( expDiff < 0 ) goto bExpBigger;
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
return propagateFloat128NaN( a, b );
}
float_raise( float_flag_invalid );
z.low = float128_default_nan_low;
z.high = float128_default_nan_high;
return z;
}
if ( aExp == 0 ) {
aExp = 1;
bExp = 1;
}
if ( bSig0 < aSig0 ) goto aBigger;
if ( aSig0 < bSig0 ) goto bBigger;
if ( bSig1 < aSig1 ) goto aBigger;
if ( aSig1 < bSig1 ) goto bBigger;
return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 );
bExpBigger:
if ( bExp == 0x7FFF ) {
if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
}
if ( aExp == 0 ) {
++expDiff;
}
else {
aSig0 |= LIT64( 0x4000000000000000 );
}
shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
bSig0 |= LIT64( 0x4000000000000000 );
bBigger:
sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
zExp = bExp;
zSign ^= 1;
goto normalizeRoundAndPack;
aExpBigger:
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
return a;
}
if ( bExp == 0 ) {
--expDiff;
}
else {
bSig0 |= LIT64( 0x4000000000000000 );
}
shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
aSig0 |= LIT64( 0x4000000000000000 );
aBigger:
sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
zExp = aExp;
normalizeRoundAndPack:
--zExp;
return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of adding the quadruple-precision floating-point values
| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
| for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 float128_add( float128 a, float128 b )
{
flag aSign, bSign;
 
aSign = extractFloat128Sign( a );
bSign = extractFloat128Sign( b );
if ( aSign == bSign ) {
return addFloat128Sigs( a, b, aSign );
}
else {
return subFloat128Sigs( a, b, aSign );
}
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of subtracting the quadruple-precision floating-point
| values `a' and `b'. The operation is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 float128_sub( float128 a, float128 b )
{
flag aSign, bSign;
 
aSign = extractFloat128Sign( a );
bSign = extractFloat128Sign( b );
if ( aSign == bSign ) {
return subFloat128Sigs( a, b, aSign );
}
else {
return addFloat128Sigs( a, b, aSign );
}
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of multiplying the quadruple-precision floating-point
| values `a' and `b'. The operation is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 float128_mul( float128 a, float128 b )
{
flag aSign, bSign, zSign;
int32 aExp, bExp, zExp;
bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
float128 z;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
bSig1 = extractFloat128Frac1( b );
bSig0 = extractFloat128Frac0( b );
bExp = extractFloat128Exp( b );
bSign = extractFloat128Sign( b );
zSign = aSign ^ bSign;
if ( aExp == 0x7FFF ) {
if ( ( aSig0 | aSig1 )
|| ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
return propagateFloat128NaN( a, b );
}
if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
return packFloat128( zSign, 0x7FFF, 0, 0 );
}
if ( bExp == 0x7FFF ) {
if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
invalid:
float_raise( float_flag_invalid );
z.low = float128_default_nan_low;
z.high = float128_default_nan_high;
return z;
}
return packFloat128( zSign, 0x7FFF, 0, 0 );
}
if ( aExp == 0 ) {
if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
}
if ( bExp == 0 ) {
if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
}
zExp = aExp + bExp - 0x4000;
aSig0 |= LIT64( 0x0001000000000000 );
shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
zSig2 |= ( zSig3 != 0 );
if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
shift128ExtraRightJamming(
zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
++zExp;
}
return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the result of dividing the quadruple-precision floating-point value
| `a' by the corresponding value `b'. The operation is performed according to
| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 float128_div( float128 a, float128 b )
{
flag aSign, bSign, zSign;
int32 aExp, bExp, zExp;
bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
float128 z;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
bSig1 = extractFloat128Frac1( b );
bSig0 = extractFloat128Frac0( b );
bExp = extractFloat128Exp( b );
bSign = extractFloat128Sign( b );
zSign = aSign ^ bSign;
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
if ( bExp == 0x7FFF ) {
if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
goto invalid;
}
return packFloat128( zSign, 0x7FFF, 0, 0 );
}
if ( bExp == 0x7FFF ) {
if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
return packFloat128( zSign, 0, 0, 0 );
}
if ( bExp == 0 ) {
if ( ( bSig0 | bSig1 ) == 0 ) {
if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
invalid:
float_raise( float_flag_invalid );
z.low = float128_default_nan_low;
z.high = float128_default_nan_high;
return z;
}
float_raise( float_flag_divbyzero );
return packFloat128( zSign, 0x7FFF, 0, 0 );
}
normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
}
if ( aExp == 0 ) {
if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
}
zExp = aExp - bExp + 0x3FFD;
shortShift128Left(
aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
shortShift128Left(
bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
++zExp;
}
zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
while ( (sbits64) rem0 < 0 ) {
--zSig0;
add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
}
zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
if ( ( zSig1 & 0x3FFF ) <= 4 ) {
mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
while ( (sbits64) rem1 < 0 ) {
--zSig1;
add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
}
zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
}
shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the remainder of the quadruple-precision floating-point value `a'
| with respect to the corresponding value `b'. The operation is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 float128_rem( float128 a, float128 b )
{
flag aSign, bSign, zSign;
int32 aExp, bExp, expDiff;
bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
bits64 allZero, alternateASig0, alternateASig1, sigMean1;
sbits64 sigMean0;
float128 z;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
bSig1 = extractFloat128Frac1( b );
bSig0 = extractFloat128Frac0( b );
bExp = extractFloat128Exp( b );
bSign = extractFloat128Sign( b );
if ( aExp == 0x7FFF ) {
if ( ( aSig0 | aSig1 )
|| ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
return propagateFloat128NaN( a, b );
}
goto invalid;
}
if ( bExp == 0x7FFF ) {
if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
return a;
}
if ( bExp == 0 ) {
if ( ( bSig0 | bSig1 ) == 0 ) {
invalid:
float_raise( float_flag_invalid );
z.low = float128_default_nan_low;
z.high = float128_default_nan_high;
return z;
}
normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
}
if ( aExp == 0 ) {
if ( ( aSig0 | aSig1 ) == 0 ) return a;
normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
}
expDiff = aExp - bExp;
if ( expDiff < -1 ) return a;
shortShift128Left(
aSig0 | LIT64( 0x0001000000000000 ),
aSig1,
15 - ( expDiff < 0 ),
&aSig0,
&aSig1
);
shortShift128Left(
bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
q = le128( bSig0, bSig1, aSig0, aSig1 );
if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
expDiff -= 64;
while ( 0 < expDiff ) {
q = estimateDiv128To64( aSig0, aSig1, bSig0 );
q = ( 4 < q ) ? q - 4 : 0;
mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
expDiff -= 61;
}
if ( -64 < expDiff ) {
q = estimateDiv128To64( aSig0, aSig1, bSig0 );
q = ( 4 < q ) ? q - 4 : 0;
q >>= - expDiff;
shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
expDiff += 52;
if ( expDiff < 0 ) {
shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
}
else {
shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
}
mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
}
else {
shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
}
do {
alternateASig0 = aSig0;
alternateASig1 = aSig1;
++q;
sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
} while ( 0 <= (sbits64) aSig0 );
add128(
aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
if ( ( sigMean0 < 0 )
|| ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
aSig0 = alternateASig0;
aSig1 = alternateASig1;
}
zSign = ( (sbits64) aSig0 < 0 );
if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
return
normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 );
 
}
 
/*----------------------------------------------------------------------------
| Returns the square root of the quadruple-precision floating-point value `a'.
| The operation is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
float128 float128_sqrt( float128 a )
{
flag aSign;
int32 aExp, zExp;
bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
float128 z;
 
aSig1 = extractFloat128Frac1( a );
aSig0 = extractFloat128Frac0( a );
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
if ( aExp == 0x7FFF ) {
if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a );
if ( ! aSign ) return a;
goto invalid;
}
if ( aSign ) {
if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
invalid:
float_raise( float_flag_invalid );
z.low = float128_default_nan_low;
z.high = float128_default_nan_high;
return z;
}
if ( aExp == 0 ) {
if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
}
zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
aSig0 |= LIT64( 0x0001000000000000 );
zSig0 = estimateSqrt32( aExp, aSig0>>17 );
shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
doubleZSig0 = zSig0<<1;
mul64To128( zSig0, zSig0, &term0, &term1 );
sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
while ( (sbits64) rem0 < 0 ) {
--zSig0;
doubleZSig0 -= 2;
add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
}
zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
if ( ( zSig1 & 0x1FFF ) <= 5 ) {
if ( zSig1 == 0 ) zSig1 = 1;
mul64To128( doubleZSig0, zSig1, &term1, &term2 );
sub128( rem1, 0, term1, term2, &rem1, &rem2 );
mul64To128( zSig1, zSig1, &term2, &term3 );
sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
while ( (sbits64) rem1 < 0 ) {
--zSig1;
shortShift128Left( 0, zSig1, 1, &term2, &term3 );
term3 |= 1;
term2 |= doubleZSig0;
add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
}
zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
}
shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 );
return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is equal to
| the corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float128_eq( float128 a, float128 b )
{
 
if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
&& ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
|| ( ( extractFloat128Exp( b ) == 0x7FFF )
&& ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
) {
if ( float128_is_signaling_nan( a )
|| float128_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
return
( a.low == b.low )
&& ( ( a.high == b.high )
|| ( ( a.low == 0 )
&& ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
);
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is less than
| or equal to the corresponding value `b', and 0 otherwise. The comparison
| is performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float128_le( float128 a, float128 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
&& ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
|| ( ( extractFloat128Exp( b ) == 0x7FFF )
&& ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
) {
float_raise( float_flag_invalid );
return 0;
}
aSign = extractFloat128Sign( a );
bSign = extractFloat128Sign( b );
if ( aSign != bSign ) {
return
aSign
|| ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
== 0 );
}
return
aSign ? le128( b.high, b.low, a.high, a.low )
: le128( a.high, a.low, b.high, b.low );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. The comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float128_lt( float128 a, float128 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
&& ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
|| ( ( extractFloat128Exp( b ) == 0x7FFF )
&& ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
) {
float_raise( float_flag_invalid );
return 0;
}
aSign = extractFloat128Sign( a );
bSign = extractFloat128Sign( b );
if ( aSign != bSign ) {
return
aSign
&& ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
!= 0 );
}
return
aSign ? lt128( b.high, b.low, a.high, a.low )
: lt128( a.high, a.low, b.high, b.low );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is equal to
| the corresponding value `b', and 0 otherwise. The invalid exception is
| raised if either operand is a NaN. Otherwise, the comparison is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float128_eq_signaling( float128 a, float128 b )
{
 
if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
&& ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
|| ( ( extractFloat128Exp( b ) == 0x7FFF )
&& ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
) {
float_raise( float_flag_invalid );
return 0;
}
return
( a.low == b.low )
&& ( ( a.high == b.high )
|| ( ( a.low == 0 )
&& ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
);
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is less than
| or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
| cause an exception. Otherwise, the comparison is performed according to the
| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float128_le_quiet( float128 a, float128 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
&& ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
|| ( ( extractFloat128Exp( b ) == 0x7FFF )
&& ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
) {
if ( float128_is_signaling_nan( a )
|| float128_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
aSign = extractFloat128Sign( a );
bSign = extractFloat128Sign( b );
if ( aSign != bSign ) {
return
aSign
|| ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
== 0 );
}
return
aSign ? le128( b.high, b.low, a.high, a.low )
: le128( a.high, a.low, b.high, b.low );
 
}
 
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is less than
| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
| exception. Otherwise, the comparison is performed according to the IEC/IEEE
| Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
 
flag float128_lt_quiet( float128 a, float128 b )
{
flag aSign, bSign;
 
if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
&& ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
|| ( ( extractFloat128Exp( b ) == 0x7FFF )
&& ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
) {
if ( float128_is_signaling_nan( a )
|| float128_is_signaling_nan( b ) ) {
float_raise( float_flag_invalid );
}
return 0;
}
aSign = extractFloat128Sign( a );
bSign = extractFloat128Sign( b );
if ( aSign != bSign ) {
return
aSign
&& ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
!= 0 );
}
return
aSign ? lt128( b.high, b.low, a.high, a.low )
: lt128( a.high, a.low, b.high, b.low );
 
}
 
#endif
 
/testCases.h
0,0 → 1,73
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
void testCases_setLevel( int8 );
 
void testCases_initSequence( int8 );
enum {
testCases_sequence_a_int32,
#ifdef BITS64
testCases_sequence_a_int64,
#endif
testCases_sequence_a_float32,
testCases_sequence_ab_float32,
testCases_sequence_a_float64,
testCases_sequence_ab_float64,
#ifdef FLOATX80
testCases_sequence_a_floatx80,
testCases_sequence_ab_floatx80,
#endif
#ifdef FLOAT128
testCases_sequence_a_float128,
testCases_sequence_ab_float128,
#endif
};
 
extern uint32 testCases_total;
extern flag testCases_done;
 
void testCases_next( void );
 
extern int32 testCases_a_int32;
#ifdef BITS64
extern int64 testCases_a_int64;
#endif
extern float32 testCases_a_float32;
extern float32 testCases_b_float32;
extern float64 testCases_a_float64;
extern float64 testCases_b_float64;
#ifdef FLOATX80
extern floatx80 testCases_a_floatx80;
extern floatx80 testCases_b_floatx80;
#endif
#ifdef FLOAT128
extern float128 testCases_a_float128;
extern float128 testCases_b_float128;
#endif
 
/writeHex.h
0,0 → 1,46
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
//#include <stdio.h>
 
void writeHex_flag( flag/*, FILE* */ );
void writeHex_bits32( bits32/*, FILE* */ );
#ifdef BITS64
void writeHex_bits64( bits64/*, FILE* */ );
#endif
void writeHex_float32( float32/*, FILE* */ );
void writeHex_float64( float64/*, FILE* */ );
#ifdef FLOATX80
void writeHex_floatx80( floatx80/*, FILE* */ );
#endif
#ifdef FLOAT128
void writeHex_float128( float128/*, FILE* */ );
#endif
void writeHex_float_flags( uint8/*, FILE* */ );
 
/testfloat.c
0,0 → 1,287
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
 
===============================================================================
*/
/*
#include <stdlib.h>
#include <signal.h>
#include <string.h>
*/
#include "support.h" // OR1k support C library
#include "milieu.h"
#include "fail.h"
#include "softfloat.h"
#include "testCases.h"
#include "testLoops.h"
#include "systflags.h"
#include "testFunction.h"
/*
static void catchSIGINT( int signalCode )
{
 
if ( stop ) exit( EXIT_FAILURE );
stop = TRUE;
 
}
*/
 
// Running this bare metal standalone for OR1K - hard set the configuration
int
main( int argc, char **argv )
{
// char *argPtr; // Unused variable
flag functionArgument;
uint8 functionCode;
int8 operands, roundingPrecision, roundingMode;
 
fail_programName = "testfloat";
//if ( argc <= 1 ) goto writeHelpMessage;
testCases_setLevel( 1 );
trueName = "soft";
testName = "syst";
errorStop = FALSE;
forever = FALSE;
maxErrorCount = 20;
trueFlagsPtr = &float_exception_flags;
testFlagsFunctionPtr = syst_float_flags_clear;
tininessModeName = 0;
functionArgument = FALSE;
functionCode = 0;
operands = 0;
roundingPrecision = 0;
roundingMode = 0;
// "all" setting:
functionArgument = TRUE;
functionCode = 0;
operands = 0;
/*
--argc;
++argv;
while ( argc && ( argPtr = argv[ 0 ] ) ) {
if ( argPtr[ 0 ] == '-' ) ++argPtr;
if ( strcmp( argPtr, "help" ) == 0 ) {
writeHelpMessage:
fputs(
"testfloat [<option>...] <function>\n"
" <option>: (* is default)\n"
" -help --Write this message and exit.\n"
" -list --List all testable functions and exit.\n"
" -level <num> --Testing level <num> (1 or 2).\n"
" * -level 1\n"
" -errors <num> --Stop each function test after <num> errors.\n"
" * -errors 20\n"
" -errorstop --Exit after first function with any error.\n"
" -forever --Test one function repeatedly (implies `-level 2').\n"
" -checkNaNs --Check for bitwise correctness of NaN results.\n"
#ifdef FLOATX80
" -precision32 --Only test rounding precision equivalent to float32.\n"
" -precision64 --Only test rounding precision equivalent to float64.\n"
" -precision80 --Only test maximum rounding precision.\n"
#endif
" -nearesteven --Only test rounding to nearest/even.\n"
" -tozero --Only test rounding to zero.\n"
" -down --Only test rounding down.\n"
" -up --Only test rounding up.\n"
" -tininessbefore --Underflow tininess detected before rounding.\n"
" -tininessafter --Underflow tininess detected after rounding.\n"
" <function>:\n"
" int32_to_<float> <float>_add <float>_eq\n"
" <float>_to_int32 <float>_sub <float>_le\n"
" <float>_to_int32_round_to_zero <float>_mul <float>_lt\n"
#ifdef BITS64
" int64_to_<float> <float>_div <float>_eq_signaling\n"
" <float>_to_int64 <float>_rem <float>_le_quiet\n"
" <float>_to_int64_round_to_zero <float>_lt_quiet\n"
" <float>_to_<float>\n"
" <float>_round_to_int\n"
" <float>_sqrt\n"
#else
" <float>_to_<float> <float>_div <float>_eq_signaling\n"
" <float>_round_to_int <float>_rem <float>_le_quiet\n"
" <float>_sqrt <float>_lt_quiet\n"
#endif
" -all1 --All 1-operand functions.\n"
" -all2 --All 2-operand functions.\n"
" -all --All functions.\n"
" <float>:\n"
" float32 --Single precision.\n"
" float64 --Double precision.\n"
#ifdef FLOATX80
" floatx80 --Extended double precision.\n"
#endif
#ifdef FLOAT128
" float128 --Quadruple precision.\n"
#endif
,
stdout
);
return EXIT_SUCCESS;
}
else if ( strcmp( argPtr, "list" ) == 0 ) {
for ( functionCode = 1;
functionCode < NUM_FUNCTIONS;
++functionCode
) {
if ( functionExists[ functionCode ] ) {
puts( functions[ functionCode ].name );
}
}
return EXIT_SUCCESS;
}
else if ( strcmp( argPtr, "level" ) == 0 ) {
if ( argc < 2 ) goto optionError;
testCases_setLevel( atoi( argv[ 1 ] ) );
--argc;
++argv;
}
else if ( strcmp( argPtr, "level1" ) == 0 ) {
testCases_setLevel( 1 );
}
else if ( strcmp( argPtr, "level2" ) == 0 ) {
testCases_setLevel( 2 );
}
else if ( strcmp( argPtr, "errors" ) == 0 ) {
if ( argc < 2 ) {
optionError:
fail( "`%s' option requires numeric argument", argv[ 0 ] );
}
maxErrorCount = atoi( argv[ 1 ] );
--argc;
++argv;
}
else if ( strcmp( argPtr, "errorstop" ) == 0 ) {
errorStop = TRUE;
}
else if ( strcmp( argPtr, "forever" ) == 0 ) {
testCases_setLevel( 2 );
forever = TRUE;
}
else if ( ( strcmp( argPtr, "checkNaNs" ) == 0 )
|| ( strcmp( argPtr, "checknans" ) == 0 ) ) {
checkNaNs = TRUE;
}
#ifdef FLOATX80
else if ( strcmp( argPtr, "precision32" ) == 0 ) {
roundingPrecision = 32;
}
else if ( strcmp( argPtr, "precision64" ) == 0 ) {
roundingPrecision = 64;
}
else if ( strcmp( argPtr, "precision80" ) == 0 ) {
roundingPrecision = 80;
}
#endif
else if ( ( strcmp( argPtr, "nearesteven" ) == 0 )
|| ( strcmp( argPtr, "nearest_even" ) == 0 ) ) {
roundingMode = ROUND_NEAREST_EVEN;
}
else if ( ( strcmp( argPtr, "tozero" ) == 0 )
|| ( strcmp( argPtr, "to_zero" ) == 0 ) ) {
roundingMode = ROUND_TO_ZERO;
}
else if ( strcmp( argPtr, "down" ) == 0 ) {
roundingMode = ROUND_DOWN;
}
else if ( strcmp( argPtr, "up" ) == 0 ) {
roundingMode = ROUND_UP;
}
else if ( strcmp( argPtr, "tininessbefore" ) == 0 ) {
float_detect_tininess = float_tininess_before_rounding;
}
else if ( strcmp( argPtr, "tininessafter" ) == 0 ) {
float_detect_tininess = float_tininess_after_rounding;
}
else if ( strcmp( argPtr, "all1" ) == 0 ) {
functionArgument = TRUE;
functionCode = 0;
operands = 1;
}
else if ( strcmp( argPtr, "all2" ) == 0 ) {
functionArgument = TRUE;
functionCode = 0;
operands = 2;
}
else if ( strcmp( argPtr, "all" ) == 0 ) {
functionArgument = TRUE;
functionCode = 0;
operands = 0;
}
else {
for ( functionCode = 1;
functionCode < NUM_FUNCTIONS;
++functionCode
) {
if ( strcmp( argPtr, functions[ functionCode ].name ) == 0 ) {
break;
}
}
if ( functionCode == NUM_FUNCTIONS ) {
fail( "Invalid option or function `%s'", argv[ 0 ] );
}
if ( ! functionExists[ functionCode ] ) {
fail(
"Function `%s' is not supported or cannot be tested",
argPtr
);
}
functionArgument = TRUE;
}
--argc;
++argv;
}
*/
if ( ! functionArgument ) fail( "Function argument required" );
// (void) signal( SIGINT, catchSIGINT );
// (void) signal( SIGTERM, catchSIGINT );
if ( functionCode ) {
if ( forever ) {
if ( ! roundingPrecision ) roundingPrecision = 80;
if ( ! roundingMode ) roundingMode = ROUND_NEAREST_EVEN;
}
testFunction( functionCode, roundingPrecision, roundingMode );
}
else {
 
for ( functionCode = 1;
functionCode < NUM_FUNCTIONS;
++functionCode
) {
if ( functionExists[ functionCode ] ) {
testFunction(
functionCode, roundingPrecision, roundingMode );
}
}
 
}
exitWithStatus();
 
// Should never reach here
return 1;
 
}
 
/softfloat.h
0,0 → 1,263
 
/*============================================================================
 
This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
Package, Release 2b.
 
Written by John R. Hauser. This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704. Funding was partially provided by the
National Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
arithmetic/SoftFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
=============================================================================*/
 
/*----------------------------------------------------------------------------
| The macro `FLOATX80' must be defined to enable the extended double-precision
| floating-point format `floatx80'. If this macro is not defined, the
| `floatx80' type will not be defined, and none of the functions that either
| input or output the `floatx80' type will be defined. The same applies to
| the `FLOAT128' macro and the quadruple-precision format `float128'.
*----------------------------------------------------------------------------*/
//#define FLOATX80
//#define FLOAT128
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point types.
*----------------------------------------------------------------------------*/
typedef unsigned int float32;
typedef unsigned long long float64;
#ifdef FLOATX80
typedef struct {
unsigned long long low;
unsigned short high;
} floatx80;
#endif
#ifdef FLOAT128
typedef struct {
unsigned long long low, high;
} float128;
#endif
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point underflow tininess-detection mode.
*----------------------------------------------------------------------------*/
extern signed char float_detect_tininess;
enum {
float_tininess_after_rounding = 0,
float_tininess_before_rounding = 1
};
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point rounding mode.
*----------------------------------------------------------------------------*/
extern signed char float_rounding_mode;
enum {
float_round_nearest_even = 0,
float_round_down = 1,
float_round_up = 2,
float_round_to_zero = 3
};
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point exception flags.
*----------------------------------------------------------------------------*/
extern signed char float_exception_flags;
enum {
float_flag_invalid = 1,
float_flag_divbyzero = 4,
float_flag_overflow = 8,
float_flag_underflow = 16,
float_flag_inexact = 32
};
 
/*----------------------------------------------------------------------------
| Routine to raise any or all of the software IEC/IEEE floating-point
| exception flags.
*----------------------------------------------------------------------------*/
void float_raise( signed char );
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE integer-to-floating-point conversion routines.
*----------------------------------------------------------------------------*/
float32 int32_to_float32( int );
float64 int32_to_float64( int );
#ifdef FLOATX80
floatx80 int32_to_floatx80( int );
#endif
#ifdef FLOAT128
float128 int32_to_float128( int );
#endif
float32 int64_to_float32( long long );
float64 int64_to_float64( long long );
#ifdef FLOATX80
floatx80 int64_to_floatx80( long long );
#endif
#ifdef FLOAT128
float128 int64_to_float128( long long );
#endif
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE single-precision conversion routines.
*----------------------------------------------------------------------------*/
int float32_to_int32( float32 );
int float32_to_int32_round_to_zero( float32 );
long long float32_to_int64( float32 );
long long float32_to_int64_round_to_zero( float32 );
float64 float32_to_float64( float32 );
#ifdef FLOATX80
floatx80 float32_to_floatx80( float32 );
#endif
#ifdef FLOAT128
float128 float32_to_float128( float32 );
#endif
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE single-precision operations.
*----------------------------------------------------------------------------*/
float32 float32_round_to_int( float32 );
float32 float32_add( float32, float32 );
float32 float32_sub( float32, float32 );
float32 float32_mul( float32, float32 );
float32 float32_div( float32, float32 );
float32 float32_rem( float32, float32 );
float32 float32_sqrt( float32 );
char float32_eq( float32, float32 );
char float32_le( float32, float32 );
char float32_lt( float32, float32 );
char float32_eq_signaling( float32, float32 );
char float32_le_quiet( float32, float32 );
char float32_lt_quiet( float32, float32 );
char float32_is_signaling_nan( float32 );
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision conversion routines.
*----------------------------------------------------------------------------*/
int float64_to_int32( float64 );
int float64_to_int32_round_to_zero( float64 );
long long float64_to_int64( float64 );
long long float64_to_int64_round_to_zero( float64 );
float32 float64_to_float32( float64 );
#ifdef FLOATX80
floatx80 float64_to_floatx80( float64 );
#endif
#ifdef FLOAT128
float128 float64_to_float128( float64 );
#endif
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision operations.
*----------------------------------------------------------------------------*/
float64 float64_round_to_int( float64 );
float64 float64_add( float64, float64 );
float64 float64_sub( float64, float64 );
float64 float64_mul( float64, float64 );
float64 float64_div( float64, float64 );
float64 float64_rem( float64, float64 );
float64 float64_sqrt( float64 );
char float64_eq( float64, float64 );
char float64_le( float64, float64 );
char float64_lt( float64, float64 );
char float64_eq_signaling( float64, float64 );
char float64_le_quiet( float64, float64 );
char float64_lt_quiet( float64, float64 );
char float64_is_signaling_nan( float64 );
 
#ifdef FLOATX80
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE extended double-precision conversion routines.
*----------------------------------------------------------------------------*/
int floatx80_to_int32( floatx80 );
int floatx80_to_int32_round_to_zero( floatx80 );
long long floatx80_to_int64( floatx80 );
long long floatx80_to_int64_round_to_zero( floatx80 );
float32 floatx80_to_float32( floatx80 );
float64 floatx80_to_float64( floatx80 );
#ifdef FLOAT128
float128 floatx80_to_float128( floatx80 );
#endif
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE extended double-precision rounding precision. Valid
| values are 32, 64, and 80.
*----------------------------------------------------------------------------*/
extern signed char floatx80_rounding_precision;
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE extended double-precision operations.
*----------------------------------------------------------------------------*/
floatx80 floatx80_round_to_int( floatx80 );
floatx80 floatx80_add( floatx80, floatx80 );
floatx80 floatx80_sub( floatx80, floatx80 );
floatx80 floatx80_mul( floatx80, floatx80 );
floatx80 floatx80_div( floatx80, floatx80 );
floatx80 floatx80_rem( floatx80, floatx80 );
floatx80 floatx80_sqrt( floatx80 );
char floatx80_eq( floatx80, floatx80 );
char floatx80_le( floatx80, floatx80 );
char floatx80_lt( floatx80, floatx80 );
char floatx80_eq_signaling( floatx80, floatx80 );
char floatx80_le_quiet( floatx80, floatx80 );
char floatx80_lt_quiet( floatx80, floatx80 );
char floatx80_is_signaling_nan( floatx80 );
 
#endif
 
#ifdef FLOAT128
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE quadruple-precision conversion routines.
*----------------------------------------------------------------------------*/
int float128_to_int32( float128 );
int float128_to_int32_round_to_zero( float128 );
long long float128_to_int64( float128 );
long long float128_to_int64_round_to_zero( float128 );
float32 float128_to_float32( float128 );
float64 float128_to_float64( float128 );
#ifdef FLOATX80
floatx80 float128_to_floatx80( float128 );
#endif
 
/*----------------------------------------------------------------------------
| Software IEC/IEEE quadruple-precision operations.
*----------------------------------------------------------------------------*/
float128 float128_round_to_int( float128 );
float128 float128_add( float128, float128 );
float128 float128_sub( float128, float128 );
float128 float128_mul( float128, float128 );
float128 float128_div( float128, float128 );
float128 float128_rem( float128, float128 );
float128 float128_sqrt( float128 );
char float128_eq( float128, float128 );
char float128_le( float128, float128 );
char float128_lt( float128, float128 );
char float128_eq_signaling( float128, float128 );
char float128_le_quiet( float128, float128 );
char float128_lt_quiet( float128, float128 );
char float128_is_signaling_nan( float128 );
 
#endif
 
/slowfloat.c
0,0 → 1,2123
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
#include "milieu.h"
#include "softfloat.h"
#include "slowfloat.h"
 
// From slowfloat-64.c
 
int8 slow_float_rounding_mode;
int8 slow_float_exception_flags;
int8 slow_float_detect_tininess;
#ifdef FLOATX80
int8 slow_floatx80_rounding_precision;
#endif
 
typedef struct {
bits64 a0, a1;
} bits128X;
 
typedef struct {
flag isNaN;
flag isInf;
flag isZero;
flag sign;
int32 exp;
bits128X sig;
} floatX;
 
static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
static const floatX floatXPositiveZero =
{ FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
static const floatX floatXNegativeZero =
{ FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
 
static bits128X shortShift128Left( bits128X a, int8 shiftCount )
{
int8 negShiftCount;
 
negShiftCount = ( - shiftCount & 63 );
a.a0 = ( a.a0<<shiftCount ) | ( a.a1>>negShiftCount );
a.a1 <<= shiftCount;
return a;
 
}
 
static bits128X shortShift128RightJamming( bits128X a, int8 shiftCount )
{
int8 negShiftCount;
bits64 extra;
 
negShiftCount = ( - shiftCount & 63 );
extra = a.a1<<negShiftCount;
a.a1 = ( a.a0<<negShiftCount ) | ( a.a1>>shiftCount ) | ( extra != 0 );
a.a0 >>= shiftCount;
return a;
 
}
 
static bits128X neg128( bits128X a )
{
 
if ( a.a1 == 0 ) {
a.a0 = - a.a0;
}
else {
a.a1 = - a.a1;
a.a0 = ~ a.a0;
}
return a;
 
}
 
static bits128X add128( bits128X a, bits128X b )
{
 
a.a1 += b.a1;
a.a0 += b.a0 + ( a.a1 < b.a1 );
return a;
 
}
 
static flag eq128( bits128X a, bits128X b )
{
 
return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
 
}
 
static flag le128( bits128X a, bits128X b )
{
 
return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
 
}
 
static flag lt128( bits128X a, bits128X b )
{
 
return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
 
}
 
static floatX roundFloatXTo24( flag isTiny, floatX zx )
{
bits32 roundBits;
 
zx.sig.a0 |= ( zx.sig.a1 != 0 );
zx.sig.a1 = 0;
roundBits = zx.sig.a0 & 0xFFFFFFFF;
zx.sig.a0 -= roundBits;
if ( roundBits ) {
slow_float_exception_flags |= float_flag_inexact;
if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
if ( roundBits < 0x80000000 ) goto noIncrement;
if ( ( roundBits == 0x80000000 )
&& ! ( zx.sig.a0 & LIT64( 0x100000000 ) ) ) {
goto noIncrement;
}
break;
case float_round_to_zero:
goto noIncrement;
case float_round_down:
if ( ! zx.sign ) goto noIncrement;
break;
case float_round_up:
if ( zx.sign ) goto noIncrement;
break;
}
zx.sig.a0 += LIT64( 0x100000000 );
if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
zx.sig.a0 = LIT64( 0x0080000000000000 );
++zx.exp;
}
}
noIncrement:
return zx;
 
}
 
static floatX roundFloatXTo53( flag isTiny, floatX zx )
{
int8 roundBits;
 
zx.sig.a0 |= ( zx.sig.a1 != 0 );
zx.sig.a1 = 0;
roundBits = zx.sig.a0 & 7;
zx.sig.a0 -= roundBits;
if ( roundBits ) {
slow_float_exception_flags |= float_flag_inexact;
if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
if ( roundBits < 4 ) goto noIncrement;
if ( ( roundBits == 4 ) && ! ( zx.sig.a0 & 8 ) ) goto noIncrement;
break;
case float_round_to_zero:
goto noIncrement;
case float_round_down:
if ( ! zx.sign ) goto noIncrement;
break;
case float_round_up:
if ( zx.sign ) goto noIncrement;
break;
}
zx.sig.a0 += 8;
if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
zx.sig.a0 = LIT64( 0x0080000000000000 );
++zx.exp;
}
}
noIncrement:
return zx;
 
}
 
#ifdef FLOATX80
static floatX roundFloatXTo64( flag isTiny, floatX zx )
{
int64 roundBits;
 
roundBits = zx.sig.a1 & LIT64( 0x00FFFFFFFFFFFFFF );
zx.sig.a1 -= roundBits;
if ( roundBits ) {
slow_float_exception_flags |= float_flag_inexact;
if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
if ( roundBits < LIT64( 0x0080000000000000 ) ) goto noIncrement;
if ( ( roundBits == LIT64( 0x0080000000000000 ) )
&& ! ( zx.sig.a1 & LIT64( 0x0100000000000000 ) ) ) {
goto noIncrement;
}
break;
case float_round_to_zero:
goto noIncrement;
case float_round_down:
if ( ! zx.sign ) goto noIncrement;
break;
case float_round_up:
if ( zx.sign ) goto noIncrement;
break;
}
zx.sig.a1 += LIT64( 0x0100000000000000 );
zx.sig.a0 += ( zx.sig.a1 == 0 );
if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
zx.sig.a0 = LIT64( 0x0080000000000000 );
++zx.exp;
}
}
noIncrement:
return zx;
 
}
#endif
static floatX roundFloatXTo113( flag isTiny, floatX zx )
{
int8 roundBits;
 
roundBits = zx.sig.a1 & 0x7F;
zx.sig.a1 -= roundBits;
if ( roundBits ) {
slow_float_exception_flags |= float_flag_inexact;
if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
if ( roundBits < 0x40 ) goto noIncrement;
if ( ( roundBits == 0x40 )
&& ! ( zx.sig.a1 & 0x80 ) ) goto noIncrement;
break;
case float_round_to_zero:
goto noIncrement;
case float_round_down:
if ( ! zx.sign ) goto noIncrement;
break;
case float_round_up:
if ( zx.sign ) goto noIncrement;
break;
}
zx.sig.a1 += 0x80;
zx.sig.a0 += ( zx.sig.a1 == 0 );
if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
zx.sig.a0 = LIT64( 0x0080000000000000 );
++zx.exp;
}
}
noIncrement:
return zx;
 
}
 
static floatX int32ToFloatX( int32 a )
{
floatX ax;
 
ax.isNaN = FALSE;
ax.isInf = FALSE;
ax.exp = 0; // Initialise it to keep GCC happy
ax.sign = ( a < 0 );
ax.sig.a1 = 0;
ax.sig.a0 = ax.sign ? - (bits64) a : a;
if ( a == 0 ) {
ax.isZero = TRUE;
return ax;
}
ax.isZero = FALSE;
ax.sig.a0 <<= 24;
ax.exp = 31;
while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
ax.sig.a0 <<= 1;
--ax.exp;
}
return ax;
 
}
 
static int32 floatXToInt32( floatX ax )
{
int8 savedExceptionFlags;
int32 shiftCount;
int32 z;
 
if ( ax.isInf || ax.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
return ( ax.isInf & ax.sign ) ? (sbits32) 0x80000000 : 0x7FFFFFFF;
}
if ( ax.isZero ) return 0;
savedExceptionFlags = slow_float_exception_flags;
shiftCount = 52 - ax.exp;
if ( 56 < shiftCount ) {
ax.sig.a1 = 1;
ax.sig.a0 = 0;
}
else {
while ( 0 < shiftCount ) {
ax.sig = shortShift128RightJamming( ax.sig, 1 );
--shiftCount;
}
}
ax = roundFloatXTo53( FALSE, ax );
ax.sig = shortShift128RightJamming( ax.sig, 3 );
z = ax.sig.a0;
if ( ax.sign ) z = - z;
if ( ( shiftCount < 0 )
|| ( ax.sig.a0>>32 )
|| ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
) {
slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
return ax.sign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
}
return z;
 
}
 
static floatX int64ToFloatX( int64 a )
{
floatX ax;
 
ax.isNaN = FALSE;
ax.isInf = FALSE;
ax.exp = 0; // Init to keep GCC happy
ax.sign = ( a < 0 );
ax.sig.a1 = ax.sign ? - a : a;
ax.sig.a0 = 0;
if ( a == 0 ) {
ax.isZero = TRUE;
return ax;
}
ax.isZero = FALSE;
ax.sig = shortShift128Left( ax.sig, 56 );
ax.exp = 63;
while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
ax.sig = shortShift128Left( ax.sig, 1 );
--ax.exp;
}
return ax;
 
}
 
static int64 floatXToInt64( floatX ax )
{
int8 savedExceptionFlags;
int32 shiftCount;
int64 z;
 
if ( ax.isInf || ax.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
return
( ax.isInf & ax.sign ) ? (sbits64) LIT64( 0x8000000000000000 )
: LIT64( 0x7FFFFFFFFFFFFFFF );
}
if ( ax.isZero ) return 0;
savedExceptionFlags = slow_float_exception_flags;
shiftCount = 112 - ax.exp;
if ( 116 < shiftCount ) {
ax.sig.a1 = 1;
ax.sig.a0 = 0;
}
else {
while ( 0 < shiftCount ) {
ax.sig = shortShift128RightJamming( ax.sig, 1 );
--shiftCount;
}
}
ax = roundFloatXTo113( FALSE, ax );
ax.sig = shortShift128RightJamming( ax.sig, 7 );
z = ax.sig.a1;
if ( ax.sign ) z = - z;
if ( ( shiftCount < 0 )
|| ax.sig.a0
|| ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
) {
slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
return
ax.sign ? (sbits64) LIT64( 0x8000000000000000 )
: LIT64( 0x7FFFFFFFFFFFFFFF );
}
return z;
 
}
 
static floatX float32ToFloatX( float32 a )
{
int16 expField;
floatX ax;
 
ax.isNaN = FALSE;
ax.isInf = FALSE;
ax.isZero = FALSE;
ax.exp = 0; // Init here to keep GCC happy
ax.sign = ( ( a & 0x80000000 ) != 0 );
expField = ( a>>23 ) & 0xFF;
ax.sig.a1 = 0;
ax.sig.a0 = a & 0x007FFFFF;
ax.sig.a0 <<= 32;
if ( expField == 0 ) {
if ( ax.sig.a0 == 0 ) {
ax.isZero = TRUE;
}
else {
expField = 1 - 0x7F;
do {
ax.sig.a0 <<= 1;
--expField;
} while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) );
ax.exp = expField;
}
}
else if ( expField == 0xFF ) {
if ( ax.sig.a0 == 0 ) {
ax.isInf = TRUE;
}
else {
ax.isNaN = TRUE;
}
}
else {
ax.sig.a0 |= LIT64( 0x0080000000000000 );
ax.exp = expField - 0x7F;
}
return ax;
 
}
 
static float32 floatXToFloat32( floatX zx )
{
floatX savedZ;
flag isTiny;
int32 expField;
float32 z = 0;// Init this to keep GCC happy.
 
if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
if ( zx.isNaN ) return 0xFFFFFFFF;
while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
++zx.exp;
}
while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
zx.sig = shortShift128Left( zx.sig, 1 );
--zx.exp;
}
savedZ = zx;
isTiny =
( slow_float_detect_tininess == float_tininess_before_rounding )
&& ( zx.exp + 0x7F <= 0 );
zx = roundFloatXTo24( isTiny, zx );
expField = zx.exp + 0x7F;
if ( 0xFF <= expField ) {
slow_float_exception_flags |=
float_flag_overflow | float_flag_inexact;
if ( zx.sign ) {
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
case float_round_down:
z = 0xFF800000;
break;
case float_round_to_zero:
case float_round_up:
z = 0xFF7FFFFF;
break;
}
}
else {
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
case float_round_up:
z = 0x7F800000;
break;
case float_round_to_zero:
case float_round_down:
z = 0x7F7FFFFF;
break;
}
}
return z;
}
if ( expField <= 0 ) {
isTiny = TRUE;
zx = savedZ;
expField = zx.exp + 0x7F;
if ( expField < -27 ) {
zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
zx.sig.a0 = 0;
}
else {
while ( expField <= 0 ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
++expField;
}
}
zx = roundFloatXTo24( isTiny, zx );
expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
}
z = expField;
z <<= 23;
if ( zx.sign ) z |= 0x80000000;
z |= ( zx.sig.a0>>32 ) & 0x007FFFFF;
return z;
 
}
 
static floatX float64ToFloatX( float64 a )
{
int16 expField;
floatX ax;
 
ax.isNaN = FALSE;
ax.isInf = FALSE;
ax.isZero = FALSE;
ax.exp = 0 ; // Init to keep GCC happy
ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
expField = ( a>>52 ) & 0x7FF;
ax.sig.a1 = 0;
ax.sig.a0 = a & LIT64( 0x000FFFFFFFFFFFFF );
if ( expField == 0 ) {
if ( ax.sig.a0 == 0 ) {
ax.isZero = TRUE;
}
else {
expField = 1 - 0x3FF;
do {
ax.sig.a0 <<= 1;
--expField;
} while ( ax.sig.a0 < LIT64( 0x0010000000000000 ) );
ax.exp = expField;
}
}
else if ( expField == 0x7FF ) {
if ( ax.sig.a0 == 0 ) {
ax.isInf = TRUE;
}
else {
ax.isNaN = TRUE;
}
}
else {
ax.exp = expField - 0x3FF;
ax.sig.a0 |= LIT64( 0x0010000000000000 );
}
ax.sig.a0 <<= 3;
return ax;
 
}
 
static float64 floatXToFloat64( floatX zx )
{
floatX savedZ;
flag isTiny;
int32 expField;
float64 z = 0 ;// Init to keep GCC happy
 
if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
if ( zx.isInf ) {
return
zx.sign ? LIT64( 0xFFF0000000000000 )
: LIT64( 0x7FF0000000000000 );
}
if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
++zx.exp;
}
while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
zx.sig = shortShift128Left( zx.sig, 1 );
--zx.exp;
}
savedZ = zx;
isTiny =
( slow_float_detect_tininess == float_tininess_before_rounding )
&& ( zx.exp + 0x3FF <= 0 );
zx = roundFloatXTo53( isTiny, zx );
expField = zx.exp + 0x3FF;
if ( 0x7FF <= expField ) {
slow_float_exception_flags |=
float_flag_overflow | float_flag_inexact;
if ( zx.sign ) {
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
case float_round_down:
z = LIT64( 0xFFF0000000000000 );
break;
case float_round_to_zero:
case float_round_up:
z = LIT64( 0xFFEFFFFFFFFFFFFF );
break;
}
}
else {
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
case float_round_up:
z = LIT64( 0x7FF0000000000000 );
break;
case float_round_to_zero:
case float_round_down:
z = LIT64( 0x7FEFFFFFFFFFFFFF );
break;
}
}
return z;
}
if ( expField <= 0 ) {
isTiny = TRUE;
zx = savedZ;
expField = zx.exp + 0x3FF;
if ( expField < -56 ) {
zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
zx.sig.a0 = 0;
}
else {
while ( expField <= 0 ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
++expField;
}
}
zx = roundFloatXTo53( isTiny, zx );
expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
}
zx.sig.a0 >>= 3;
z = expField;
z <<= 52;
if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
z |= zx.sig.a0 & LIT64( 0x000FFFFFFFFFFFFF );
return z;
 
}
 
#ifdef FLOATX80
 
static floatX floatx80ToFloatX( floatx80 a )
{
int32 expField;
floatX ax;
 
ax.isNaN = FALSE;
ax.isInf = FALSE;
ax.isZero = FALSE;
ax.sign = ( ( a.high & 0x8000 ) != 0 );
expField = a.high & 0x7FFF;
ax.sig.a1 = a.low;
ax.sig.a0 = 0;
if ( expField == 0 ) {
if ( ax.sig.a1 == 0 ) {
ax.isZero = TRUE;
}
else {
expField = 1 - 0x3FFF;
while ( ax.sig.a1 < LIT64( 0x8000000000000000 ) ) {
ax.sig.a1 <<= 1;
--expField;
}
ax.exp = expField;
}
}
else if ( expField == 0x7FFF ) {
if ( ( ax.sig.a1 & LIT64( 0x7FFFFFFFFFFFFFFF ) ) == 0 ) {
ax.isInf = TRUE;
}
else {
ax.isNaN = TRUE;
}
}
else {
ax.exp = expField - 0x3FFF;
}
ax.sig = shortShift128Left( ax.sig, 56 );
return ax;
 
}
 
static floatx80 floatXToFloatx80( floatX zx )
{
floatX savedZ;
flag isTiny;
int32 expField;
floatx80 z;
 
if ( zx.isZero ) {
z.low = 0;
z.high = zx.sign ? 0x8000 : 0;
return z;
}
if ( zx.isInf ) {
z.low = LIT64( 0x8000000000000000 );
z.high = zx.sign ? 0xFFFF : 0x7FFF;
return z;
}
if ( zx.isNaN ) {
z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
z.high = 0xFFFF;
return z;
}
while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
++zx.exp;
}
while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
zx.sig = shortShift128Left( zx.sig, 1 );
--zx.exp;
}
savedZ = zx;
isTiny =
( slow_float_detect_tininess == float_tininess_before_rounding )
&& ( zx.exp + 0x3FFF <= 0 );
switch ( slow_floatx80_rounding_precision ) {
case 32:
zx = roundFloatXTo24( isTiny, zx );
break;
case 64:
zx = roundFloatXTo53( isTiny, zx );
break;
default:
zx = roundFloatXTo64( isTiny, zx );
break;
}
expField = zx.exp + 0x3FFF;
if ( 0x7FFF <= expField ) {
slow_float_exception_flags |=
float_flag_overflow | float_flag_inexact;
if ( zx.sign ) {
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
case float_round_down:
z.low = LIT64( 0x8000000000000000 );
z.high = 0xFFFF;
break;
case float_round_to_zero:
case float_round_up:
switch ( slow_floatx80_rounding_precision ) {
case 32:
z.low = LIT64( 0xFFFFFF0000000000 );
break;
case 64:
z.low = LIT64( 0xFFFFFFFFFFFFF800 );
break;
default:
z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
break;
}
z.high = 0xFFFE;
break;
}
}
else {
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
case float_round_up:
z.low = LIT64( 0x8000000000000000 );
z.high = 0x7FFF;
break;
case float_round_to_zero:
case float_round_down:
switch ( slow_floatx80_rounding_precision ) {
case 32:
z.low = LIT64( 0xFFFFFF0000000000 );
break;
case 64:
z.low = LIT64( 0xFFFFFFFFFFFFF800 );
break;
default:
z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
break;
}
z.high = 0x7FFE;
break;
}
}
return z;
}
if ( expField <= 0 ) {
isTiny = TRUE;
zx = savedZ;
expField = zx.exp + 0x3FFF;
if ( expField < -70 ) {
zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
zx.sig.a0 = 0;
}
else {
while ( expField <= 0 ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
++expField;
}
}
switch ( slow_floatx80_rounding_precision ) {
case 32:
zx = roundFloatXTo24( isTiny, zx );
break;
case 64:
zx = roundFloatXTo53( isTiny, zx );
break;
default:
zx = roundFloatXTo64( isTiny, zx );
break;
}
expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
}
zx.sig = shortShift128RightJamming( zx.sig, 56 );
z.low = zx.sig.a1;
z.high = expField;
if ( zx.sign ) z.high |= 0x8000;
return z;
 
}
 
#endif
 
#ifdef FLOAT128
 
static floatX float128ToFloatX( float128 a )
{
int32 expField;
floatX ax;
 
ax.isNaN = FALSE;
ax.isInf = FALSE;
ax.isZero = FALSE;
ax.sign = ( ( a.high & LIT64( 0x8000000000000000 ) ) != 0 );
expField = ( a.high>>48 ) & 0x7FFF;
ax.sig.a1 = a.low;
ax.sig.a0 = a.high & LIT64( 0x0000FFFFFFFFFFFF );
if ( expField == 0 ) {
if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
ax.isZero = TRUE;
}
else {
expField = 1 - 0x3FFF;
do {
ax.sig = shortShift128Left( ax.sig, 1 );
--expField;
} while ( ax.sig.a0 < LIT64( 0x0001000000000000 ) );
ax.exp = expField;
}
}
else if ( expField == 0x7FFF ) {
if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
ax.isInf = TRUE;
}
else {
ax.isNaN = TRUE;
}
}
else {
ax.exp = expField - 0x3FFF;
ax.sig.a0 |= LIT64( 0x0001000000000000 );
}
ax.sig = shortShift128Left( ax.sig, 7 );
return ax;
 
}
 
static float128 floatXToFloat128( floatX zx )
{
floatX savedZ;
flag isTiny;
int32 expField;
float128 z;
 
if ( zx.isZero ) {
z.low = 0;
z.high = zx.sign ? LIT64( 0x8000000000000000 ) : 0;
return z;
}
if ( zx.isInf ) {
z.low = 0;
z.high =
zx.sign ? LIT64( 0xFFFF000000000000 )
: LIT64( 0x7FFF000000000000 );
return z;
}
if ( zx.isNaN ) {
z.high = z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
return z;
}
while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
++zx.exp;
}
while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
zx.sig = shortShift128Left( zx.sig, 1 );
--zx.exp;
}
savedZ = zx;
isTiny =
( slow_float_detect_tininess == float_tininess_before_rounding )
&& ( zx.exp + 0x3FFF <= 0 );
zx = roundFloatXTo113( isTiny, zx );
expField = zx.exp + 0x3FFF;
if ( 0x7FFF <= expField ) {
slow_float_exception_flags |=
float_flag_overflow | float_flag_inexact;
if ( zx.sign ) {
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
case float_round_down:
z.low = 0;
z.high = LIT64( 0xFFFF000000000000 );
break;
case float_round_to_zero:
case float_round_up:
z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
z.high = LIT64( 0xFFFEFFFFFFFFFFFF );
break;
}
}
else {
switch ( slow_float_rounding_mode ) {
case float_round_nearest_even:
case float_round_up:
z.low = 0;
z.high = LIT64( 0x7FFF000000000000 );
break;
case float_round_to_zero:
case float_round_down:
z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
z.high = LIT64( 0x7FFEFFFFFFFFFFFF );
break;
}
}
return z;
}
if ( expField <= 0 ) {
isTiny = TRUE;
zx = savedZ;
expField = zx.exp + 0x3FFF;
if ( expField < -120 ) {
zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
zx.sig.a0 = 0;
}
else {
while ( expField <= 0 ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
++expField;
}
}
zx = roundFloatXTo113( isTiny, zx );
expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
}
zx.sig = shortShift128RightJamming( zx.sig, 7 );
z.low = zx.sig.a1;
z.high = expField;
z.high <<= 48;
if ( zx.sign ) z.high |= LIT64( 0x8000000000000000 );
z.high |= zx.sig.a0 & LIT64( 0x0000FFFFFFFFFFFF );
return z;
 
}
 
#endif
 
static floatX floatXInvalid( void )
{
 
slow_float_exception_flags |= float_flag_invalid;
return floatXNaN;
 
}
 
static floatX floatXRoundToInt( floatX ax )
{
int32 shiftCount;
 
if ( ax.isNaN || ax.isInf ) return ax;
shiftCount = 112 - ax.exp;
if ( shiftCount <= 0 ) return ax;
if ( 119 < shiftCount ) {
ax.exp = 112;
ax.sig.a1 = ! ax.isZero;
ax.sig.a0 = 0;
}
else {
while ( 0 < shiftCount ) {
ax.sig = shortShift128RightJamming( ax.sig, 1 );
++ax.exp;
--shiftCount;
}
}
ax = roundFloatXTo113( FALSE, ax );
if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
return ax;
 
}
 
static floatX floatXAdd( floatX ax, floatX bx )
{
int32 expDiff;
floatX zx;
 
if ( ax.isNaN ) return ax;
if ( bx.isNaN ) return bx;
if ( ax.isInf && bx.isInf ) {
if ( ax.sign == bx.sign ) return ax;
return floatXInvalid();
}
if ( ax.isInf ) return ax;
if ( bx.isInf ) return bx;
if ( ax.isZero && bx.isZero ) {
if ( ax.sign == bx.sign ) return ax;
goto completeCancellation;
}
if ( ( ax.sign != bx.sign )
&& ( ax.exp == bx.exp )
&& eq128( ax.sig, bx.sig )
) {
completeCancellation:
return
( slow_float_rounding_mode == float_round_down ) ?
floatXNegativeZero
: floatXPositiveZero;
}
if ( ax.isZero ) return bx;
if ( bx.isZero ) return ax;
expDiff = ax.exp - bx.exp;
if ( expDiff < 0 ) {
zx = ax;
zx.exp = bx.exp;
if ( expDiff < -120 ) {
zx.sig.a1 = 1;
zx.sig.a0 = 0;
}
else {
while ( expDiff < 0 ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
++expDiff;
}
}
if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
zx.sign = bx.sign;
zx.sig = add128( zx.sig, bx.sig );
}
else {
zx = bx;
zx.exp = ax.exp;
if ( 120 < expDiff ) {
zx.sig.a1 = 1;
zx.sig.a0 = 0;
}
else {
while ( 0 < expDiff ) {
zx.sig = shortShift128RightJamming( zx.sig, 1 );
--expDiff;
}
}
if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
zx.sign = ax.sign;
zx.sig = add128( zx.sig, ax.sig );
}
if ( zx.sig.a0 & LIT64( 0x8000000000000000 ) ) {
zx.sig = neg128( zx.sig );
zx.sign = ! zx.sign;
}
return zx;
 
}
 
static floatX floatXMul( floatX ax, floatX bx )
{
int8 bitNum;
floatX zx;
 
if ( ax.isNaN ) return ax;
if ( bx.isNaN ) return bx;
if ( ax.isInf ) {
if ( bx.isZero ) return floatXInvalid();
if ( bx.sign ) ax.sign = ! ax.sign;
return ax;
}
if ( bx.isInf ) {
if ( ax.isZero ) return floatXInvalid();
if ( ax.sign ) bx.sign = ! bx.sign;
return bx;
}
zx = ax;
zx.sign ^= bx.sign;
if ( ax.isZero || bx.isZero ) {
return zx.sign ? floatXNegativeZero : floatXPositiveZero;
}
zx.exp += bx.exp + 1;
zx.sig.a1 = 0;
zx.sig.a0 = 0;
for ( bitNum = 0; bitNum < 119; ++bitNum ) {
if ( bx.sig.a1 & 2 ) zx.sig = add128( zx.sig, ax.sig );
bx.sig = shortShift128RightJamming( bx.sig, 1 );
zx.sig = shortShift128RightJamming( zx.sig, 1 );
}
return zx;
 
}
 
static floatX floatXDiv( floatX ax, floatX bx )
{
bits128X negBSig;
int8 bitNum;
floatX zx;
 
if ( ax.isNaN ) return ax;
if ( bx.isNaN ) return bx;
if ( ax.isInf ) {
if ( bx.isInf ) return floatXInvalid();
if ( bx.sign ) ax.sign = ! ax.sign;
return ax;
}
if ( bx.isZero ) {
if ( ax.isZero ) return floatXInvalid();
slow_float_exception_flags |= float_flag_divbyzero;
if ( ax.sign ) bx.sign = ! bx.sign;
bx.isZero = FALSE;
bx.isInf = TRUE;
return bx;
}
zx = ax;
zx.sign ^= bx.sign;
if ( ax.isZero || bx.isInf ) {
return zx.sign ? floatXNegativeZero : floatXPositiveZero;
}
zx.exp -= bx.exp + 1;
zx.sig.a1 = 0;
zx.sig.a0 = 0;
negBSig = neg128( bx.sig );
for ( bitNum = 0; bitNum < 120; ++bitNum ) {
if ( le128( bx.sig, ax.sig ) ) {
zx.sig.a1 |= 1;
ax.sig = add128( ax.sig, negBSig );
}
ax.sig = shortShift128Left( ax.sig, 1 );
zx.sig = shortShift128Left( zx.sig, 1 );
}
if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
return zx;
 
}
 
static floatX floatXRem( floatX ax, floatX bx )
{
bits128X negBSig;
flag lastQuotientBit;
bits128X savedASig;
 
if ( ax.isNaN ) return ax;
if ( bx.isNaN ) return bx;
if ( ax.isInf || bx.isZero ) return floatXInvalid();
if ( ax.isZero || bx.isInf ) return ax;
--bx.exp;
if ( ax.exp < bx.exp ) return ax;
bx.sig = shortShift128Left( bx.sig, 1 );
negBSig = neg128( bx.sig );
while ( bx.exp < ax.exp ) {
if ( le128( bx.sig, ax.sig ) ) ax.sig = add128( ax.sig, negBSig );
ax.sig = shortShift128Left( ax.sig, 1 );
--ax.exp;
}
lastQuotientBit = le128( bx.sig, ax.sig );
if ( lastQuotientBit ) ax.sig = add128( ax.sig, negBSig );
savedASig = ax.sig;
ax.sig = neg128( add128( ax.sig, negBSig ) );
if ( lt128( ax.sig, savedASig ) ) {
ax.sign = ! ax.sign;
}
else if ( lt128( savedASig, ax.sig ) ) {
ax.sig = savedASig;
}
else {
if ( lastQuotientBit ) {
ax.sign = ! ax.sign;
}
else {
ax.sig = savedASig;
}
}
if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
return ax;
 
}
 
static floatX floatXSqrt( floatX ax )
{
int8 bitNum;
bits128X bitSig, savedASig;
floatX zx;
 
if ( ax.isNaN || ax.isZero ) return ax;
if ( ax.sign ) return floatXInvalid();
if ( ax.isInf ) return ax;
zx = ax;
zx.exp >>= 1;
if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift128RightJamming( ax.sig, 1 );
zx.sig.a1 = 0;
zx.sig.a0 = 0;
bitSig.a1 = 0;
bitSig.a0 = LIT64( 0x0080000000000000 );
for ( bitNum = 0; bitNum < 120; ++bitNum ) {
savedASig = ax.sig;
ax.sig = add128( ax.sig, neg128( zx.sig ) );
ax.sig = shortShift128Left( ax.sig, 1 );
ax.sig = add128( ax.sig, neg128( bitSig ) );
if ( ax.sig.a0 & LIT64( 0x8000000000000000 ) ) {
ax.sig = shortShift128Left( savedASig, 1 );
}
else {
zx.sig.a1 |= bitSig.a1;
zx.sig.a0 |= bitSig.a0;
}
bitSig = shortShift128RightJamming( bitSig, 1 );
}
if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
return zx;
 
}
 
static flag floatXEq( floatX ax, floatX bx )
{
 
if ( ax.isNaN || bx.isNaN ) return FALSE;
if ( ax.isZero && bx.isZero ) return TRUE;
if ( ax.sign != bx.sign ) return FALSE;
if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
return ( ax.exp == bx.exp ) && eq128( ax.sig, bx.sig );
 
}
 
static flag floatXLe( floatX ax, floatX bx )
{
 
if ( ax.isNaN || bx.isNaN ) return FALSE;
if ( ax.isZero && bx.isZero ) return TRUE;
if ( ax.sign != bx.sign ) return ax.sign;
if ( ax.sign ) {
if ( ax.isInf || bx.isZero ) return TRUE;
if ( bx.isInf || ax.isZero ) return FALSE;
if ( bx.exp < ax.exp ) return TRUE;
if ( ax.exp < bx.exp ) return FALSE;
return le128( bx.sig, ax.sig );
}
else {
if ( bx.isInf || ax.isZero ) return TRUE;
if ( ax.isInf || bx.isZero ) return FALSE;
if ( ax.exp < bx.exp ) return TRUE;
if ( bx.exp < ax.exp ) return FALSE;
return le128( ax.sig, bx.sig );
}
 
}
 
static flag floatXLt( floatX ax, floatX bx )
{
 
if ( ax.isNaN || bx.isNaN ) return FALSE;
if ( ax.isZero && bx.isZero ) return FALSE;
if ( ax.sign != bx.sign ) return ax.sign;
if ( ax.isInf && bx.isInf ) return FALSE;
if ( ax.sign ) {
if ( ax.isInf || bx.isZero ) return TRUE;
if ( bx.isInf || ax.isZero ) return FALSE;
if ( bx.exp < ax.exp ) return TRUE;
if ( ax.exp < bx.exp ) return FALSE;
return lt128( bx.sig, ax.sig );
}
else {
if ( bx.isInf || ax.isZero ) return TRUE;
if ( ax.isInf || bx.isZero ) return FALSE;
if ( ax.exp < bx.exp ) return TRUE;
if ( bx.exp < ax.exp ) return FALSE;
return lt128( ax.sig, bx.sig );
}
 
}
 
float32 slow_int32_to_float32( int32 a )
{
 
return floatXToFloat32( int32ToFloatX( a ) );
 
}
 
float64 slow_int32_to_float64( int32 a )
{
 
return floatXToFloat64( int32ToFloatX( a ) );
 
}
 
#ifdef FLOATX80
 
floatx80 slow_int32_to_floatx80( int32 a )
{
 
return floatXToFloatx80( int32ToFloatX( a ) );
 
}
 
#endif
 
#ifdef FLOAT128
 
float128 slow_int32_to_float128( int32 a )
{
 
return floatXToFloat128( int32ToFloatX( a ) );
 
}
 
#endif
 
float32 slow_int64_to_float32( int64 a )
{
 
return floatXToFloat32( int64ToFloatX( a ) );
 
}
 
float64 slow_int64_to_float64( int64 a )
{
 
return floatXToFloat64( int64ToFloatX( a ) );
 
}
 
#ifdef FLOATX80
 
floatx80 slow_int64_to_floatx80( int64 a )
{
 
return floatXToFloatx80( int64ToFloatX( a ) );
 
}
 
#endif
 
#ifdef FLOAT128
 
float128 slow_int64_to_float128( int64 a )
{
 
return floatXToFloat128( int64ToFloatX( a ) );
 
}
 
#endif
 
int32 slow_float32_to_int32( float32 a )
{
 
return floatXToInt32( float32ToFloatX( a ) );
 
}
 
int32 slow_float32_to_int32_round_to_zero( float32 a )
{
int8 savedRoundingMode;
int32 z;
 
savedRoundingMode = slow_float_rounding_mode;
slow_float_rounding_mode = float_round_to_zero;
z = floatXToInt32( float32ToFloatX( a ) );
slow_float_rounding_mode = savedRoundingMode;
return z;
 
}
 
int64 slow_float32_to_int64( float32 a )
{
 
return floatXToInt64( float32ToFloatX( a ) );
 
}
 
int64 slow_float32_to_int64_round_to_zero( float32 a )
{
int8 savedRoundingMode;
int64 z;
 
savedRoundingMode = slow_float_rounding_mode;
slow_float_rounding_mode = float_round_to_zero;
z = floatXToInt64( float32ToFloatX( a ) );
slow_float_rounding_mode = savedRoundingMode;
return z;
 
}
 
float64 slow_float32_to_float64( float32 a )
{
 
return floatXToFloat64( float32ToFloatX( a ) );
 
}
 
#ifdef FLOATX80
 
floatx80 slow_float32_to_floatx80( float32 a )
{
 
return floatXToFloatx80( float32ToFloatX( a ) );
 
}
 
#endif
 
#ifdef FLOAT128
 
float128 slow_float32_to_float128( float32 a )
{
 
return floatXToFloat128( float32ToFloatX( a ) );
 
}
 
#endif
 
float32 slow_float32_round_to_int( float32 a )
{
 
return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
 
}
 
float32 slow_float32_add( float32 a, float32 b )
{
 
return
floatXToFloat32(
floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
 
}
 
float32 slow_float32_sub( float32 a, float32 b )
{
 
b ^= 0x80000000;
return
floatXToFloat32(
floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
 
}
 
float32 slow_float32_mul( float32 a, float32 b )
{
 
return
floatXToFloat32(
floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
 
}
 
float32 slow_float32_div( float32 a, float32 b )
{
 
return
floatXToFloat32(
floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
 
}
 
float32 slow_float32_rem( float32 a, float32 b )
{
 
return
floatXToFloat32(
floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
 
}
 
float32 slow_float32_sqrt( float32 a )
{
 
return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
 
}
 
flag slow_float32_eq( float32 a, float32 b )
{
 
return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
 
}
 
flag slow_float32_le( float32 a, float32 b )
{
floatX ax, bx;
 
ax = float32ToFloatX( a );
bx = float32ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXLe( ax, bx );
 
}
 
flag slow_float32_lt( float32 a, float32 b )
{
floatX ax, bx;
 
ax = float32ToFloatX( a );
bx = float32ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXLt( ax, bx );
 
}
 
flag slow_float32_eq_signaling( float32 a, float32 b )
{
floatX ax, bx;
 
ax = float32ToFloatX( a );
bx = float32ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXEq( ax, bx );
 
}
 
flag slow_float32_le_quiet( float32 a, float32 b )
{
 
return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
 
}
 
flag slow_float32_lt_quiet( float32 a, float32 b )
{
 
return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
 
}
 
int32 slow_float64_to_int32( float64 a )
{
 
return floatXToInt32( float64ToFloatX( a ) );
 
}
 
int32 slow_float64_to_int32_round_to_zero( float64 a )
{
int8 savedRoundingMode;
int32 z;
 
savedRoundingMode = slow_float_rounding_mode;
slow_float_rounding_mode = float_round_to_zero;
z = floatXToInt32( float64ToFloatX( a ) );
slow_float_rounding_mode = savedRoundingMode;
return z;
 
}
 
int64 slow_float64_to_int64( float64 a )
{
 
return floatXToInt64( float64ToFloatX( a ) );
 
}
 
int64 slow_float64_to_int64_round_to_zero( float64 a )
{
int8 savedRoundingMode;
int64 z;
 
savedRoundingMode = slow_float_rounding_mode;
slow_float_rounding_mode = float_round_to_zero;
z = floatXToInt64( float64ToFloatX( a ) );
slow_float_rounding_mode = savedRoundingMode;
return z;
 
}
 
float32 slow_float64_to_float32( float64 a )
{
 
return floatXToFloat32( float64ToFloatX( a ) );
 
}
 
#ifdef FLOATX80
 
floatx80 slow_float64_to_floatx80( float64 a )
{
 
return floatXToFloatx80( float64ToFloatX( a ) );
 
}
 
#endif
 
#ifdef FLOAT128
 
float128 slow_float64_to_float128( float64 a )
{
 
return floatXToFloat128( float64ToFloatX( a ) );
 
}
 
#endif
 
float64 slow_float64_round_to_int( float64 a )
{
 
return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
 
}
 
float64 slow_float64_add( float64 a, float64 b )
{
 
return
floatXToFloat64(
floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
 
}
 
float64 slow_float64_sub( float64 a, float64 b )
{
 
b ^= LIT64( 0x8000000000000000 );
return
floatXToFloat64(
floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
 
}
 
float64 slow_float64_mul( float64 a, float64 b )
{
 
return
floatXToFloat64(
floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
 
}
 
float64 slow_float64_div( float64 a, float64 b )
{
 
return
floatXToFloat64(
floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
 
}
 
float64 slow_float64_rem( float64 a, float64 b )
{
 
return
floatXToFloat64(
floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
 
}
 
float64 slow_float64_sqrt( float64 a )
{
 
return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
 
}
 
flag slow_float64_eq( float64 a, float64 b )
{
 
return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
 
}
 
flag slow_float64_le( float64 a, float64 b )
{
floatX ax, bx;
 
ax = float64ToFloatX( a );
bx = float64ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXLe( ax, bx );
 
}
 
flag slow_float64_lt( float64 a, float64 b )
{
floatX ax, bx;
 
ax = float64ToFloatX( a );
bx = float64ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXLt( ax, bx );
 
}
 
flag slow_float64_eq_signaling( float64 a, float64 b )
{
floatX ax, bx;
 
ax = float64ToFloatX( a );
bx = float64ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXEq( ax, bx );
 
}
 
flag slow_float64_le_quiet( float64 a, float64 b )
{
 
return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
 
}
 
flag slow_float64_lt_quiet( float64 a, float64 b )
{
 
return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
 
}
 
#ifdef FLOATX80
 
int32 slow_floatx80_to_int32( floatx80 a )
{
 
return floatXToInt32( floatx80ToFloatX( a ) );
 
}
 
int32 slow_floatx80_to_int32_round_to_zero( floatx80 a )
{
int8 savedRoundingMode;
int32 z;
 
savedRoundingMode = slow_float_rounding_mode;
slow_float_rounding_mode = float_round_to_zero;
z = floatXToInt32( floatx80ToFloatX( a ) );
slow_float_rounding_mode = savedRoundingMode;
return z;
 
}
 
int64 slow_floatx80_to_int64( floatx80 a )
{
 
return floatXToInt64( floatx80ToFloatX( a ) );
 
}
 
int64 slow_floatx80_to_int64_round_to_zero( floatx80 a )
{
int8 savedRoundingMode;
int64 z;
 
savedRoundingMode = slow_float_rounding_mode;
slow_float_rounding_mode = float_round_to_zero;
z = floatXToInt64( floatx80ToFloatX( a ) );
slow_float_rounding_mode = savedRoundingMode;
return z;
 
}
 
float32 slow_floatx80_to_float32( floatx80 a )
{
 
return floatXToFloat32( floatx80ToFloatX( a ) );
 
}
 
float64 slow_floatx80_to_float64( floatx80 a )
{
 
return floatXToFloat64( floatx80ToFloatX( a ) );
 
}
 
#ifdef FLOAT128
 
float128 slow_floatx80_to_float128( floatx80 a )
{
 
return floatXToFloat128( floatx80ToFloatX( a ) );
 
}
 
#endif
 
floatx80 slow_floatx80_round_to_int( floatx80 a )
{
 
return floatXToFloatx80( floatXRoundToInt( floatx80ToFloatX( a ) ) );
 
}
 
floatx80 slow_floatx80_add( floatx80 a, floatx80 b )
{
 
return
floatXToFloatx80(
floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
 
}
 
floatx80 slow_floatx80_sub( floatx80 a, floatx80 b )
{
 
b.high ^= 0x8000;
return
floatXToFloatx80(
floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
 
}
 
floatx80 slow_floatx80_mul( floatx80 a, floatx80 b )
{
 
return
floatXToFloatx80(
floatXMul( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
 
}
 
floatx80 slow_floatx80_div( floatx80 a, floatx80 b )
{
 
return
floatXToFloatx80(
floatXDiv( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
 
}
 
floatx80 slow_floatx80_rem( floatx80 a, floatx80 b )
{
 
return
floatXToFloatx80(
floatXRem( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
 
}
 
floatx80 slow_floatx80_sqrt( floatx80 a )
{
 
return floatXToFloatx80( floatXSqrt( floatx80ToFloatX( a ) ) );
 
}
 
flag slow_floatx80_eq( floatx80 a, floatx80 b )
{
 
return floatXEq( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
 
}
 
flag slow_floatx80_le( floatx80 a, floatx80 b )
{
floatX ax, bx;
 
ax = floatx80ToFloatX( a );
bx = floatx80ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXLe( ax, bx );
 
}
 
flag slow_floatx80_lt( floatx80 a, floatx80 b )
{
floatX ax, bx;
 
ax = floatx80ToFloatX( a );
bx = floatx80ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXLt( ax, bx );
 
}
 
flag slow_floatx80_eq_signaling( floatx80 a, floatx80 b )
{
floatX ax, bx;
 
ax = floatx80ToFloatX( a );
bx = floatx80ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXEq( ax, bx );
 
}
 
flag slow_floatx80_le_quiet( floatx80 a, floatx80 b )
{
 
return floatXLe( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
 
}
 
flag slow_floatx80_lt_quiet( floatx80 a, floatx80 b )
{
 
return floatXLt( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
 
}
 
#endif
 
#ifdef FLOAT128
 
int32 slow_float128_to_int32( float128 a )
{
 
return floatXToInt32( float128ToFloatX( a ) );
 
}
 
int32 slow_float128_to_int32_round_to_zero( float128 a )
{
int8 savedRoundingMode;
int32 z;
 
savedRoundingMode = slow_float_rounding_mode;
slow_float_rounding_mode = float_round_to_zero;
z = floatXToInt32( float128ToFloatX( a ) );
slow_float_rounding_mode = savedRoundingMode;
return z;
 
}
 
int64 slow_float128_to_int64( float128 a )
{
 
return floatXToInt64( float128ToFloatX( a ) );
 
}
 
int64 slow_float128_to_int64_round_to_zero( float128 a )
{
int8 savedRoundingMode;
int64 z;
 
savedRoundingMode = slow_float_rounding_mode;
slow_float_rounding_mode = float_round_to_zero;
z = floatXToInt64( float128ToFloatX( a ) );
slow_float_rounding_mode = savedRoundingMode;
return z;
 
}
 
float32 slow_float128_to_float32( float128 a )
{
 
return floatXToFloat32( float128ToFloatX( a ) );
 
}
 
float64 slow_float128_to_float64( float128 a )
{
 
return floatXToFloat64( float128ToFloatX( a ) );
 
}
 
#ifdef FLOATX80
 
floatx80 slow_float128_to_floatx80( float128 a )
{
 
return floatXToFloatx80( float128ToFloatX( a ) );
 
}
 
#endif
 
float128 slow_float128_round_to_int( float128 a )
{
 
return floatXToFloat128( floatXRoundToInt( float128ToFloatX( a ) ) );
 
}
 
float128 slow_float128_add( float128 a, float128 b )
{
 
return
floatXToFloat128(
floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
 
}
 
float128 slow_float128_sub( float128 a, float128 b )
{
 
b.high ^= LIT64( 0x8000000000000000 );
return
floatXToFloat128(
floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
 
}
 
float128 slow_float128_mul( float128 a, float128 b )
{
 
return
floatXToFloat128(
floatXMul( float128ToFloatX( a ), float128ToFloatX( b ) ) );
 
}
 
float128 slow_float128_div( float128 a, float128 b )
{
 
return
floatXToFloat128(
floatXDiv( float128ToFloatX( a ), float128ToFloatX( b ) ) );
 
}
 
float128 slow_float128_rem( float128 a, float128 b )
{
 
return
floatXToFloat128(
floatXRem( float128ToFloatX( a ), float128ToFloatX( b ) ) );
 
}
 
float128 slow_float128_sqrt( float128 a )
{
 
return floatXToFloat128( floatXSqrt( float128ToFloatX( a ) ) );
 
}
 
flag slow_float128_eq( float128 a, float128 b )
{
 
return floatXEq( float128ToFloatX( a ), float128ToFloatX( b ) );
 
}
 
flag slow_float128_le( float128 a, float128 b )
{
floatX ax, bx;
 
ax = float128ToFloatX( a );
bx = float128ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXLe( ax, bx );
 
}
 
flag slow_float128_lt( float128 a, float128 b )
{
floatX ax, bx;
 
ax = float128ToFloatX( a );
bx = float128ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXLt( ax, bx );
 
}
 
flag slow_float128_eq_signaling( float128 a, float128 b )
{
floatX ax, bx;
 
ax = float128ToFloatX( a );
bx = float128ToFloatX( b );
if ( ax.isNaN || bx.isNaN ) {
slow_float_exception_flags |= float_flag_invalid;
}
return floatXEq( ax, bx );
 
}
 
flag slow_float128_le_quiet( float128 a, float128 b )
{
 
return floatXLe( float128ToFloatX( a ), float128ToFloatX( b ) );
 
}
 
flag slow_float128_lt_quiet( float128 a, float128 b )
{
 
return floatXLt( float128ToFloatX( a ), float128ToFloatX( b ) );
 
}
 
#endif
 
/fail.c
0,0 → 1,53
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
/*
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
*/
#include "support.h" // OR1k support C library
#include "milieu.h"
#include "fail.h"
 
char *fail_programName = "";
 
void fail( const char *message, ... )
{
va_list varArgs;
// No stderr in or1k support library, just print normally
printf( "%s: ", fail_programName );
va_start( varArgs, message );
printf( message, varArgs );
va_end( varArgs );
printf( ".\n" );
exit( 0x1 );
 
}
 
/systflags.c
0,0 → 1,88
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
#include "milieu.h"
#include "systflags.h"
#include "spr-defs.h"
//#include <stdio.h>
 
// Float flag values, from softfloat.h
enum {
float_flag_invalid = 1,
float_flag_divbyzero = 4,
float_flag_overflow = 8,
float_flag_underflow = 16,
float_flag_inexact = 32
};
 
/*
-------------------------------------------------------------------------------
Clears the system's IEC/IEEE floating-point exception flags. Returns the
previous value of the flags.
-------------------------------------------------------------------------------
*/
int8 syst_float_flags_clear( void )
{
 
// Read the FPCSR
unsigned int spr = SPR_FPCSR;
unsigned int value;
int8 flags = 0;
// Read the SPR
asm("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr));
// Extract the flags from OR1K's FPCSR, put into testfloat's flags format
if (value & SPR_FPCSR_IXF)
flags |= float_flag_inexact;
 
if (value & SPR_FPCSR_UNF)
flags |= float_flag_underflow;
 
if (value & SPR_FPCSR_OVF)
flags |= float_flag_overflow;
 
if (value & SPR_FPCSR_DZF)
flags |= float_flag_divbyzero;
 
if (value & SPR_FPCSR_IVF)
flags |= float_flag_invalid;
// printf("testfloat: getting flags, FPCSR: 0x%x, softfloatflags: 0x%x\n",
// value & SPR_FPCSR_ALLF, flags);
 
// Clear flags in FPCSR
value &= ~(SPR_FPCSR_ALLF);
// Write value back to FPCSR
asm("l.mtspr\t\t%0,%1,0": : "r" (spr), "r" (value));
 
return flags;
 
}
 
/slowfloat.h
0,0 → 1,171
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
extern int8 slow_float_rounding_mode;
extern int8 slow_float_exception_flags;
extern int8 slow_float_detect_tininess;
#ifdef FLOATX80
extern int8 slow_floatx80_rounding_precision;
#endif
 
float32 slow_int32_to_float32( int32 );
float64 slow_int32_to_float64( int32 );
#ifdef FLOATX80
floatx80 slow_int32_to_floatx80( int32 );
#endif
#ifdef FLOAT128
float128 slow_int32_to_float128( int32 );
#endif
#ifdef BITS64
float32 slow_int64_to_float32( int64 );
float64 slow_int64_to_float64( int64 );
#ifdef FLOATX80
floatx80 slow_int64_to_floatx80( int64 );
#endif
#ifdef FLOAT128
float128 slow_int64_to_float128( int64 );
#endif
#endif
 
int32 slow_float32_to_int32( float32 );
int32 slow_float32_to_int32_round_to_zero( float32 );
#ifdef BITS64
int64 slow_float32_to_int64( float32 );
int64 slow_float32_to_int64_round_to_zero( float32 );
#endif
float64 slow_float32_to_float64( float32 );
#ifdef FLOATX80
floatx80 slow_float32_to_floatx80( float32 );
#endif
#ifdef FLOAT128
float128 slow_float32_to_float128( float32 );
#endif
 
float32 slow_float32_round_to_int( float32 );
float32 slow_float32_add( float32, float32 );
float32 slow_float32_sub( float32, float32 );
float32 slow_float32_mul( float32, float32 );
float32 slow_float32_div( float32, float32 );
float32 slow_float32_rem( float32, float32 );
float32 slow_float32_sqrt( float32 );
flag slow_float32_eq( float32, float32 );
flag slow_float32_le( float32, float32 );
flag slow_float32_lt( float32, float32 );
flag slow_float32_eq_signaling( float32, float32 );
flag slow_float32_le_quiet( float32, float32 );
flag slow_float32_lt_quiet( float32, float32 );
 
int32 slow_float64_to_int32( float64 );
int32 slow_float64_to_int32_round_to_zero( float64 );
#ifdef BITS64
int64 slow_float64_to_int64( float64 );
int64 slow_float64_to_int64_round_to_zero( float64 );
#endif
float32 slow_float64_to_float32( float64 );
#ifdef FLOATX80
floatx80 slow_float64_to_floatx80( float64 );
#endif
#ifdef FLOAT128
float128 slow_float64_to_float128( float64 );
#endif
 
float64 slow_float64_round_to_int( float64 );
float64 slow_float64_add( float64, float64 );
float64 slow_float64_sub( float64, float64 );
float64 slow_float64_mul( float64, float64 );
float64 slow_float64_div( float64, float64 );
float64 slow_float64_rem( float64, float64 );
float64 slow_float64_sqrt( float64 );
flag slow_float64_eq( float64, float64 );
flag slow_float64_le( float64, float64 );
flag slow_float64_lt( float64, float64 );
flag slow_float64_eq_signaling( float64, float64 );
flag slow_float64_le_quiet( float64, float64 );
flag slow_float64_lt_quiet( float64, float64 );
 
#ifdef FLOATX80
 
int32 slow_floatx80_to_int32( floatx80 );
int32 slow_floatx80_to_int32_round_to_zero( floatx80 );
#ifdef BITS64
int64 slow_floatx80_to_int64( floatx80 );
int64 slow_floatx80_to_int64_round_to_zero( floatx80 );
#endif
float32 slow_floatx80_to_float32( floatx80 );
float64 slow_floatx80_to_float64( floatx80 );
#ifdef FLOAT128
float128 slow_floatx80_to_float128( floatx80 );
#endif
 
floatx80 slow_floatx80_round_to_int( floatx80 );
floatx80 slow_floatx80_add( floatx80, floatx80 );
floatx80 slow_floatx80_sub( floatx80, floatx80 );
floatx80 slow_floatx80_mul( floatx80, floatx80 );
floatx80 slow_floatx80_div( floatx80, floatx80 );
floatx80 slow_floatx80_rem( floatx80, floatx80 );
floatx80 slow_floatx80_sqrt( floatx80 );
flag slow_floatx80_eq( floatx80, floatx80 );
flag slow_floatx80_le( floatx80, floatx80 );
flag slow_floatx80_lt( floatx80, floatx80 );
flag slow_floatx80_eq_signaling( floatx80, floatx80 );
flag slow_floatx80_le_quiet( floatx80, floatx80 );
flag slow_floatx80_lt_quiet( floatx80, floatx80 );
 
#endif
 
#ifdef FLOAT128
 
int32 slow_float128_to_int32( float128 );
int32 slow_float128_to_int32_round_to_zero( float128 );
#ifdef BITS64
int64 slow_float128_to_int64( float128 );
int64 slow_float128_to_int64_round_to_zero( float128 );
#endif
float32 slow_float128_to_float32( float128 );
float64 slow_float128_to_float64( float128 );
#ifdef FLOATX80
floatx80 slow_float128_to_floatx80( float128 );
#endif
 
float128 slow_float128_round_to_int( float128 );
float128 slow_float128_add( float128, float128 );
float128 slow_float128_sub( float128, float128 );
float128 slow_float128_mul( float128, float128 );
float128 slow_float128_div( float128, float128 );
float128 slow_float128_rem( float128, float128 );
float128 slow_float128_sqrt( float128 );
flag slow_float128_eq( float128, float128 );
flag slow_float128_le( float128, float128 );
flag slow_float128_lt( float128, float128 );
flag slow_float128_eq_signaling( float128, float128 );
flag slow_float128_le_quiet( float128, float128 );
flag slow_float128_lt_quiet( float128, float128 );
 
#endif
 
/random.c
0,0 → 1,71
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
/*
#include <stdlib.h>
*/
#include "support.h" // OR1k support C library
#include "milieu.h"
#include "random.h"
 
uint8 randomUint8( void )
{
 
return (bits8) ( rand()>>4 );
 
}
 
uint16 randomUint16( void )
{
 
return ( ( rand() & 0x0FF0 )<<4 ) | ( ( rand()>>4 ) & 0xFF );
 
}
 
uint32 randomUint32( void )
{
 
return
( ( (uint32) ( rand() & 0x0FF0 ) )<<20 )
| ( ( (uint32) ( rand() & 0x0FF0 ) )<<12 )
| ( ( rand() & 0x0FF0 )<<4 )
| ( ( rand()>>4 ) & 0xFF );
 
}
 
#ifdef BITS64
 
uint64 randomUint64( void )
{
 
return ( ( (uint64) randomUint32() )<<32 ) | randomUint32();
 
}
 
#endif
 
/fail.h
0,0 → 1,33
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
extern char *fail_programName;
 
void fail( const char *, ... );
 
/systflags.h
0,0 → 1,37
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
/*
-------------------------------------------------------------------------------
Target-specific function for clearing the system's IEC/IEEE floating-point
exception flags. The previous value of the flags is returned.
-------------------------------------------------------------------------------
*/
int8 syst_float_flags_clear( void );
 
/random.h
0,0 → 1,36
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
uint8 randomUint8( void );
uint16 randomUint16( void );
uint32 randomUint32( void );
#ifdef BITS64
uint64 randomUint64( void );
#endif
 
/testFunction.c
0,0 → 1,1161
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
#include "support.h" // OR1k support C library
#include "milieu.h"
#include "softfloat.h"
#include "testCases.h"
#include "testLoops.h"
#include "systmodes.h"
#include "systflags.h"
#include "systfloat.h"
#include "testFunction.h"
 
const functionT functions[ NUM_FUNCTIONS ] = {
{ 0, 0, 0, 0 },
{ "int32_to_float32", 1, FALSE, TRUE },
{ "int32_to_float64", 1, FALSE, FALSE },
{ "int32_to_floatx80", 1, FALSE, FALSE },
{ "int32_to_float128", 1, FALSE, FALSE },
{ "int64_to_float32", 1, FALSE, TRUE },
{ "int64_to_float64", 1, FALSE, TRUE },
{ "int64_to_floatx80", 1, FALSE, FALSE },
{ "int64_to_float128", 1, FALSE, FALSE },
{ "float32_to_int32", 1, FALSE, TRUE },
{ "float32_to_int32_round_to_zero", 1, FALSE, FALSE },
{ "float32_to_int64", 1, FALSE, TRUE },
{ "float32_to_int64_round_to_zero", 1, FALSE, FALSE },
{ "float32_to_float64", 1, FALSE, FALSE },
{ "float32_to_floatx80", 1, FALSE, FALSE },
{ "float32_to_float128", 1, FALSE, FALSE },
{ "float32_round_to_int", 1, FALSE, TRUE },
{ "float32_add", 2, FALSE, TRUE },
{ "float32_sub", 2, FALSE, TRUE },
{ "float32_mul", 2, FALSE, TRUE },
{ "float32_div", 2, FALSE, TRUE },
{ "float32_rem", 2, FALSE, FALSE },
{ "float32_sqrt", 1, FALSE, TRUE },
{ "float32_eq", 2, FALSE, FALSE },
{ "float32_le", 2, FALSE, FALSE },
{ "float32_lt", 2, FALSE, FALSE },
{ "float32_eq_signaling", 2, FALSE, FALSE },
{ "float32_le_quiet", 2, FALSE, FALSE },
{ "float32_lt_quiet", 2, FALSE, FALSE },
{ "float64_to_int32", 1, FALSE, TRUE },
{ "float64_to_int32_round_to_zero", 1, FALSE, FALSE },
{ "float64_to_int64", 1, FALSE, TRUE },
{ "float64_to_int64_round_to_zero", 1, FALSE, FALSE },
{ "float64_to_float32", 1, FALSE, TRUE },
{ "float64_to_floatx80", 1, FALSE, FALSE },
{ "float64_to_float128", 1, FALSE, FALSE },
{ "float64_round_to_int", 1, FALSE, TRUE },
{ "float64_add", 2, FALSE, TRUE },
{ "float64_sub", 2, FALSE, TRUE },
{ "float64_mul", 2, FALSE, TRUE },
{ "float64_div", 2, FALSE, TRUE },
{ "float64_rem", 2, FALSE, FALSE },
{ "float64_sqrt", 1, FALSE, TRUE },
{ "float64_eq", 2, FALSE, FALSE },
{ "float64_le", 2, FALSE, FALSE },
{ "float64_lt", 2, FALSE, FALSE },
{ "float64_eq_signaling", 2, FALSE, FALSE },
{ "float64_le_quiet", 2, FALSE, FALSE },
{ "float64_lt_quiet", 2, FALSE, FALSE },
{ "floatx80_to_int32", 1, FALSE, TRUE },
{ "floatx80_to_int32_round_to_zero", 1, FALSE, FALSE },
{ "floatx80_to_int64", 1, FALSE, TRUE },
{ "floatx80_to_int64_round_to_zero", 1, FALSE, FALSE },
{ "floatx80_to_float32", 1, FALSE, TRUE },
{ "floatx80_to_float64", 1, FALSE, TRUE },
{ "floatx80_to_float128", 1, FALSE, FALSE },
{ "floatx80_round_to_int", 1, FALSE, TRUE },
{ "floatx80_add", 2, TRUE, TRUE },
{ "floatx80_sub", 2, TRUE, TRUE },
{ "floatx80_mul", 2, TRUE, TRUE },
{ "floatx80_div", 2, TRUE, TRUE },
{ "floatx80_rem", 2, FALSE, FALSE },
{ "floatx80_sqrt", 1, TRUE, TRUE },
{ "floatx80_eq", 2, FALSE, FALSE },
{ "floatx80_le", 2, FALSE, FALSE },
{ "floatx80_lt", 2, FALSE, FALSE },
{ "floatx80_eq_signaling", 2, FALSE, FALSE },
{ "floatx80_le_quiet", 2, FALSE, FALSE },
{ "floatx80_lt_quiet", 2, FALSE, FALSE },
{ "float128_to_int32", 1, FALSE, TRUE },
{ "float128_to_int32_round_to_zero", 1, FALSE, FALSE },
{ "float128_to_int64", 1, FALSE, TRUE },
{ "float128_to_int64_round_to_zero", 1, FALSE, FALSE },
{ "float128_to_float32", 1, FALSE, TRUE },
{ "float128_to_float64", 1, FALSE, TRUE },
{ "float128_to_floatx80", 1, FALSE, TRUE },
{ "float128_round_to_int", 1, FALSE, TRUE },
{ "float128_add", 2, FALSE, TRUE },
{ "float128_sub", 2, FALSE, TRUE },
{ "float128_mul", 2, FALSE, TRUE },
{ "float128_div", 2, FALSE, TRUE },
{ "float128_rem", 2, FALSE, FALSE },
{ "float128_sqrt", 1, FALSE, TRUE },
{ "float128_eq", 2, FALSE, FALSE },
{ "float128_le", 2, FALSE, FALSE },
{ "float128_lt", 2, FALSE, FALSE },
{ "float128_eq_signaling", 2, FALSE, FALSE },
{ "float128_le_quiet", 2, FALSE, FALSE },
{ "float128_lt_quiet", 2, FALSE, FALSE },
};
 
const flag functionExists[ NUM_FUNCTIONS ] = {
0,
#ifdef SYST_INT32_TO_FLOAT32
1,
#else
0,
#endif
#ifdef SYST_INT32_TO_FLOAT64
1,
#else
0,
#endif
#ifdef SYST_INT32_TO_FLOATX80
1,
#else
0,
#endif
#ifdef SYST_INT32_TO_FLOAT128
1,
#else
0,
#endif
#ifdef SYST_INT64_TO_FLOAT32
1,
#else
0,
#endif
#ifdef SYST_INT64_TO_FLOAT64
1,
#else
0,
#endif
#ifdef SYST_INT64_TO_FLOATX80
1,
#else
0,
#endif
#ifdef SYST_INT64_TO_FLOAT128
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_TO_INT32
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_TO_INT64
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_TO_FLOAT64
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_TO_FLOATX80
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_TO_FLOAT128
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_ROUND_TO_INT
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_ADD
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_SUB
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_MUL
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_DIV
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_REM
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_SQRT
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_EQ
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_LE
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_LT
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_EQ_SIGNALING
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_LE_QUIET
1,
#else
0,
#endif
#ifdef SYST_FLOAT32_LT_QUIET
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_TO_INT32
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_TO_INT64
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_TO_FLOAT32
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_TO_FLOATX80
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_TO_FLOAT128
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_ROUND_TO_INT
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_ADD
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_SUB
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_MUL
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_DIV
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_REM
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_SQRT
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_EQ
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_LE
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_LT
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_EQ_SIGNALING
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_LE_QUIET
1,
#else
0,
#endif
#ifdef SYST_FLOAT64_LT_QUIET
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_TO_INT32
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_TO_INT32_ROUND_TO_ZERO
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_TO_INT64
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_TO_INT64_ROUND_TO_ZERO
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_TO_FLOAT32
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_TO_FLOAT64
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_TO_FLOAT128
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_ROUND_TO_INT
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_ADD
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_SUB
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_MUL
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_DIV
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_REM
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_SQRT
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_EQ
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_LE
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_LT
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_EQ_SIGNALING
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_LE_QUIET
1,
#else
0,
#endif
#ifdef SYST_FLOATX80_LT_QUIET
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_TO_INT32
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_TO_INT64
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_TO_FLOAT32
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_TO_FLOAT64
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_TO_FLOATX80
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_ROUND_TO_INT
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_ADD
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_SUB
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_MUL
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_DIV
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_REM
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_SQRT
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_EQ
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_LE
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_LT
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_EQ_SIGNALING
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_LE_QUIET
1,
#else
0,
#endif
#ifdef SYST_FLOAT128_LT_QUIET
1,
#else
0,
#endif
};
 
static void
testFunctionVariety(
uint8 functionCode, int8 roundingPrecision, int8 roundingMode )
{
uint8 roundingCode;
 
functionName = functions[ functionCode ].name;
#ifdef FLOATX80
if ( roundingPrecision == 32 ) {
roundingPrecisionName = "32";
}
else if ( roundingPrecision == 64 ) {
roundingPrecisionName = "64";
}
else if ( roundingPrecision == 80 ) {
roundingPrecisionName = "80";
}
else {
roundingPrecision = 80;
roundingPrecisionName = 0;
}
floatx80_rounding_precision = roundingPrecision;
syst_float_set_rounding_precision( roundingPrecision );
#endif
switch ( roundingMode ) {
case ROUND_NEAREST_EVEN:
roundingModeName = "nearest_even";
roundingCode = float_round_nearest_even;
break;
case ROUND_TO_ZERO:
roundingModeName = "to_zero";
roundingCode = float_round_to_zero;
break;
case ROUND_DOWN:
roundingModeName = "down";
roundingCode = float_round_down;
break;
case ROUND_UP:
roundingModeName = "up";
roundingCode = float_round_up;
break;
default:
roundingModeName = 0;
roundingCode = float_round_nearest_even;
break;
}
float_rounding_mode = roundingCode;
syst_float_set_rounding_mode( roundingCode );
printf( "Testing "/*, stderr*/ );
writeFunctionName( /*stderr*/ );
printf( ".\n" /*, stderr*/ );
switch ( functionCode ) {
#ifdef SYST_INT32_TO_FLOAT32
case INT32_TO_FLOAT32:
test_a_int32_z_float32( int32_to_float32, syst_int32_to_float32 );
break;
#endif
#ifdef SYST_INT32_TO_FLOAT64
case INT32_TO_FLOAT64:
test_a_int32_z_float64( int32_to_float64, syst_int32_to_float64 );
break;
#endif
#ifdef SYST_INT32_TO_FLOATX80
case INT32_TO_FLOATX80:
test_a_int32_z_floatx80( int32_to_floatx80, syst_int32_to_floatx80 );
break;
#endif
#ifdef SYST_INT32_TO_FLOAT128
case INT32_TO_FLOAT128:
test_a_int32_z_float128( int32_to_float128, syst_int32_to_float128 );
break;
#endif
#ifdef SYST_INT64_TO_FLOAT32
case INT64_TO_FLOAT32:
test_a_int64_z_float32( int64_to_float32, syst_int64_to_float32 );
break;
#endif
#ifdef SYST_INT64_TO_FLOAT64
case INT64_TO_FLOAT64:
test_a_int64_z_float64( int64_to_float64, syst_int64_to_float64 );
break;
#endif
#ifdef SYST_INT64_TO_FLOATX80
case INT64_TO_FLOATX80:
test_a_int64_z_floatx80( int64_to_floatx80, syst_int64_to_floatx80 );
break;
#endif
#ifdef SYST_INT64_TO_FLOAT128
case INT64_TO_FLOAT128:
test_a_int64_z_float128( int64_to_float128, syst_int64_to_float128 );
break;
#endif
#ifdef SYST_FLOAT32_TO_INT32
case FLOAT32_TO_INT32:
test_a_float32_z_int32( float32_to_int32, syst_float32_to_int32 );
break;
#endif
#ifdef SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
case FLOAT32_TO_INT32_ROUND_TO_ZERO:
syst_float_set_rounding_mode(float_round_to_zero);
test_a_float32_z_int32(
float32_to_int32_round_to_zero,
syst_float32_to_int32_round_to_zero
);
break;
#endif
#ifdef SYST_FLOAT32_TO_INT64
case FLOAT32_TO_INT64:
test_a_float32_z_int64( float32_to_int64, syst_float32_to_int64 );
break;
#endif
#ifdef SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
case FLOAT32_TO_INT64_ROUND_TO_ZERO:
test_a_float32_z_int64(
float32_to_int64_round_to_zero,
syst_float32_to_int64_round_to_zero
);
break;
#endif
#ifdef SYST_FLOAT32_TO_FLOAT64
case FLOAT32_TO_FLOAT64:
test_a_float32_z_float64(
float32_to_float64, syst_float32_to_float64 );
break;
#endif
#ifdef SYST_FLOAT32_TO_FLOATX80
case FLOAT32_TO_FLOATX80:
test_a_float32_z_floatx80(
float32_to_floatx80, syst_float32_to_floatx80 );
break;
#endif
#ifdef SYST_FLOAT32_TO_FLOAT128
case FLOAT32_TO_FLOAT128:
test_a_float32_z_float128(
float32_to_float128, syst_float32_to_float128 );
break;
#endif
#ifdef SYST_FLOAT32_ROUND_TO_INT
case FLOAT32_ROUND_TO_INT:
test_az_float32( float32_round_to_int, syst_float32_round_to_int );
break;
#endif
#ifdef SYST_FLOAT32_ADD
case FLOAT32_ADD:
test_abz_float32( float32_add, syst_float32_add );
break;
#endif
#ifdef SYST_FLOAT32_SUB
case FLOAT32_SUB:
test_abz_float32( float32_sub, syst_float32_sub );
break;
#endif
#ifdef SYST_FLOAT32_MUL
case FLOAT32_MUL:
test_abz_float32( float32_mul, syst_float32_mul );
break;
#endif
#ifdef SYST_FLOAT32_DIV
case FLOAT32_DIV:
test_abz_float32( float32_div, syst_float32_div );
break;
#endif
#ifdef SYST_FLOAT32_REM
case FLOAT32_REM:
test_abz_float32( float32_rem, syst_float32_rem );
break;
#endif
#ifdef SYST_FLOAT32_SQRT
case FLOAT32_SQRT:
test_az_float32( float32_sqrt, syst_float32_sqrt );
break;
#endif
#ifdef SYST_FLOAT32_EQ
case FLOAT32_EQ:
test_ab_float32_z_flag( float32_eq, syst_float32_eq );
break;
#endif
#ifdef SYST_FLOAT32_LE
case FLOAT32_LE:
test_ab_float32_z_flag( float32_le, syst_float32_le );
break;
#endif
#ifdef SYST_FLOAT32_LT
case FLOAT32_LT:
test_ab_float32_z_flag( float32_lt, syst_float32_lt );
break;
#endif
#ifdef SYST_FLOAT32_EQ_SIGNALING
case FLOAT32_EQ_SIGNALING:
test_ab_float32_z_flag(
float32_eq_signaling, syst_float32_eq_signaling );
break;
#endif
#ifdef SYST_FLOAT32_LE_QUIET
case FLOAT32_LE_QUIET:
test_ab_float32_z_flag( float32_le_quiet, syst_float32_le_quiet );
break;
#endif
#ifdef SYST_FLOAT32_LT_QUIET
case FLOAT32_LT_QUIET:
test_ab_float32_z_flag( float32_lt_quiet, syst_float32_lt_quiet );
break;
#endif
#ifdef SYST_FLOAT64_TO_INT32
case FLOAT64_TO_INT32:
test_a_float64_z_int32( float64_to_int32, syst_float64_to_int32 );
break;
#endif
#ifdef SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
case FLOAT64_TO_INT32_ROUND_TO_ZERO:
test_a_float64_z_int32(
float64_to_int32_round_to_zero,
syst_float64_to_int32_round_to_zero
);
break;
#endif
#ifdef SYST_FLOAT64_TO_INT64
case FLOAT64_TO_INT64:
test_a_float64_z_int64( float64_to_int64, syst_float64_to_int64 );
break;
#endif
#ifdef SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
case FLOAT64_TO_INT64_ROUND_TO_ZERO:
test_a_float64_z_int64(
float64_to_int64_round_to_zero,
syst_float64_to_int64_round_to_zero
);
break;
#endif
#ifdef SYST_FLOAT64_TO_FLOAT32
case FLOAT64_TO_FLOAT32:
test_a_float64_z_float32(
float64_to_float32, syst_float64_to_float32 );
break;
#endif
#ifdef SYST_FLOAT64_TO_FLOATX80
case FLOAT64_TO_FLOATX80:
test_a_float64_z_floatx80(
float64_to_floatx80, syst_float64_to_floatx80 );
break;
#endif
#ifdef SYST_FLOAT64_TO_FLOAT128
case FLOAT64_TO_FLOAT128:
test_a_float64_z_float128(
float64_to_float128, syst_float64_to_float128 );
break;
#endif
#ifdef SYST_FLOAT64_ROUND_TO_INT
case FLOAT64_ROUND_TO_INT:
test_az_float64( float64_round_to_int, syst_float64_round_to_int );
break;
#endif
#ifdef SYST_FLOAT64_ADD
case FLOAT64_ADD:
test_abz_float64( float64_add, syst_float64_add );
break;
#endif
#ifdef SYST_FLOAT64_SUB
case FLOAT64_SUB:
test_abz_float64( float64_sub, syst_float64_sub );
break;
#endif
#ifdef SYST_FLOAT64_MUL
case FLOAT64_MUL:
test_abz_float64( float64_mul, syst_float64_mul );
break;
#endif
#ifdef SYST_FLOAT64_DIV
case FLOAT64_DIV:
test_abz_float64( float64_div, syst_float64_div );
break;
#endif
#ifdef SYST_FLOAT64_REM
case FLOAT64_REM:
test_abz_float64( float64_rem, syst_float64_rem );
break;
#endif
#ifdef SYST_FLOAT64_SQRT
case FLOAT64_SQRT:
test_az_float64( float64_sqrt, syst_float64_sqrt );
break;
#endif
#ifdef SYST_FLOAT64_EQ
case FLOAT64_EQ:
test_ab_float64_z_flag( float64_eq, syst_float64_eq );
break;
#endif
#ifdef SYST_FLOAT64_LE
case FLOAT64_LE:
test_ab_float64_z_flag( float64_le, syst_float64_le );
break;
#endif
#ifdef SYST_FLOAT64_LT
case FLOAT64_LT:
test_ab_float64_z_flag( float64_lt, syst_float64_lt );
break;
#endif
#ifdef SYST_FLOAT64_EQ_SIGNALING
case FLOAT64_EQ_SIGNALING:
test_ab_float64_z_flag(
float64_eq_signaling, syst_float64_eq_signaling );
break;
#endif
#ifdef SYST_FLOAT64_LE_QUIET
case FLOAT64_LE_QUIET:
test_ab_float64_z_flag( float64_le_quiet, syst_float64_le_quiet );
break;
#endif
#ifdef SYST_FLOAT64_LT_QUIET
case FLOAT64_LT_QUIET:
test_ab_float64_z_flag( float64_lt_quiet, syst_float64_lt_quiet );
break;
#endif
#ifdef SYST_FLOATX80_TO_INT32
case FLOATX80_TO_INT32:
test_a_floatx80_z_int32( floatx80_to_int32, syst_floatx80_to_int32 );
break;
#endif
#ifdef SYST_FLOATX80_TO_INT32_ROUND_TO_ZERO
case FLOATX80_TO_INT32_ROUND_TO_ZERO:
test_a_floatx80_z_int32(
floatx80_to_int32_round_to_zero,
syst_floatx80_to_int32_round_to_zero
);
break;
#endif
#ifdef SYST_FLOATX80_TO_INT64
case FLOATX80_TO_INT64:
test_a_floatx80_z_int64( floatx80_to_int64, syst_floatx80_to_int64 );
break;
#endif
#ifdef SYST_FLOATX80_TO_INT64_ROUND_TO_ZERO
case FLOATX80_TO_INT64_ROUND_TO_ZERO:
test_a_floatx80_z_int64(
floatx80_to_int64_round_to_zero,
syst_floatx80_to_int64_round_to_zero
);
break;
#endif
#ifdef SYST_FLOATX80_TO_FLOAT32
case FLOATX80_TO_FLOAT32:
test_a_floatx80_z_float32(
floatx80_to_float32, syst_floatx80_to_float32 );
break;
#endif
#ifdef SYST_FLOATX80_TO_FLOAT64
case FLOATX80_TO_FLOAT64:
test_a_floatx80_z_float64(
floatx80_to_float64, syst_floatx80_to_float64 );
break;
#endif
#ifdef SYST_FLOATX80_TO_FLOAT128
case FLOATX80_TO_FLOAT128:
test_a_floatx80_z_float128(
floatx80_to_float128, syst_floatx80_to_float128 );
break;
#endif
#ifdef SYST_FLOATX80_ROUND_TO_INT
case FLOATX80_ROUND_TO_INT:
test_az_floatx80( floatx80_round_to_int, syst_floatx80_round_to_int );
break;
#endif
#ifdef SYST_FLOATX80_ADD
case FLOATX80_ADD:
test_abz_floatx80( floatx80_add, syst_floatx80_add );
break;
#endif
#ifdef SYST_FLOATX80_SUB
case FLOATX80_SUB:
test_abz_floatx80( floatx80_sub, syst_floatx80_sub );
break;
#endif
#ifdef SYST_FLOATX80_MUL
case FLOATX80_MUL:
test_abz_floatx80( floatx80_mul, syst_floatx80_mul );
break;
#endif
#ifdef SYST_FLOATX80_DIV
case FLOATX80_DIV:
test_abz_floatx80( floatx80_div, syst_floatx80_div );
break;
#endif
#ifdef SYST_FLOATX80_REM
case FLOATX80_REM:
test_abz_floatx80( floatx80_rem, syst_floatx80_rem );
break;
#endif
#ifdef SYST_FLOATX80_SQRT
case FLOATX80_SQRT:
test_az_floatx80( floatx80_sqrt, syst_floatx80_sqrt );
break;
#endif
#ifdef SYST_FLOATX80_EQ
case FLOATX80_EQ:
test_ab_floatx80_z_flag( floatx80_eq, syst_floatx80_eq );
break;
#endif
#ifdef SYST_FLOATX80_LE
case FLOATX80_LE:
test_ab_floatx80_z_flag( floatx80_le, syst_floatx80_le );
break;
#endif
#ifdef SYST_FLOATX80_LT
case FLOATX80_LT:
test_ab_floatx80_z_flag( floatx80_lt, syst_floatx80_lt );
break;
#endif
#ifdef SYST_FLOATX80_EQ_SIGNALING
case FLOATX80_EQ_SIGNALING:
test_ab_floatx80_z_flag(
floatx80_eq_signaling, syst_floatx80_eq_signaling );
break;
#endif
#ifdef SYST_FLOATX80_LE_QUIET
case FLOATX80_LE_QUIET:
test_ab_floatx80_z_flag( floatx80_le_quiet, syst_floatx80_le_quiet );
break;
#endif
#ifdef SYST_FLOATX80_LT_QUIET
case FLOATX80_LT_QUIET:
test_ab_floatx80_z_flag( floatx80_lt_quiet, syst_floatx80_lt_quiet );
break;
#endif
#ifdef SYST_FLOAT128_TO_INT32
case FLOAT128_TO_INT32:
test_a_float128_z_int32( float128_to_int32, syst_float128_to_int32 );
break;
#endif
#ifdef SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
case FLOAT128_TO_INT32_ROUND_TO_ZERO:
test_a_float128_z_int32(
float128_to_int32_round_to_zero,
syst_float128_to_int32_round_to_zero
);
break;
#endif
#ifdef SYST_FLOAT128_TO_INT64
case FLOAT128_TO_INT64:
test_a_float128_z_int64( float128_to_int64, syst_float128_to_int64 );
break;
#endif
#ifdef SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
case FLOAT128_TO_INT64_ROUND_TO_ZERO:
test_a_float128_z_int64(
float128_to_int64_round_to_zero,
syst_float128_to_int64_round_to_zero
);
break;
#endif
#ifdef SYST_FLOAT128_TO_FLOAT32
case FLOAT128_TO_FLOAT32:
test_a_float128_z_float32(
float128_to_float32, syst_float128_to_float32 );
break;
#endif
#ifdef SYST_FLOAT128_TO_FLOAT64
case FLOAT128_TO_FLOAT64:
test_a_float128_z_float64(
float128_to_float64, syst_float128_to_float64 );
break;
#endif
#ifdef SYST_FLOAT128_TO_FLOATX80
case FLOAT128_TO_FLOATX80:
test_a_float128_z_floatx80(
float128_to_floatx80, syst_float128_to_floatx80 );
break;
#endif
#ifdef SYST_FLOAT128_ROUND_TO_INT
case FLOAT128_ROUND_TO_INT:
test_az_float128( float128_round_to_int, syst_float128_round_to_int );
break;
#endif
#ifdef SYST_FLOAT128_ADD
case FLOAT128_ADD:
test_abz_float128( float128_add, syst_float128_add );
break;
#endif
#ifdef SYST_FLOAT128_SUB
case FLOAT128_SUB:
test_abz_float128( float128_sub, syst_float128_sub );
break;
#endif
#ifdef SYST_FLOAT128_MUL
case FLOAT128_MUL:
test_abz_float128( float128_mul, syst_float128_mul );
break;
#endif
#ifdef SYST_FLOAT128_DIV
case FLOAT128_DIV:
test_abz_float128( float128_div, syst_float128_div );
break;
#endif
#ifdef SYST_FLOAT128_REM
case FLOAT128_REM:
test_abz_float128( float128_rem, syst_float128_rem );
break;
#endif
#ifdef SYST_FLOAT128_SQRT
case FLOAT128_SQRT:
test_az_float128( float128_sqrt, syst_float128_sqrt );
break;
#endif
#ifdef SYST_FLOAT128_EQ
case FLOAT128_EQ:
test_ab_float128_z_flag( float128_eq, syst_float128_eq );
break;
#endif
#ifdef SYST_FLOAT128_LE
case FLOAT128_LE:
test_ab_float128_z_flag( float128_le, syst_float128_le );
break;
#endif
#ifdef SYST_FLOAT128_LT
case FLOAT128_LT:
test_ab_float128_z_flag( float128_lt, syst_float128_lt );
break;
#endif
#ifdef SYST_FLOAT128_EQ_SIGNALING
case FLOAT128_EQ_SIGNALING:
test_ab_float128_z_flag(
float128_eq_signaling, syst_float128_eq_signaling );
break;
#endif
#ifdef SYST_FLOAT128_LE_QUIET
case FLOAT128_LE_QUIET:
test_ab_float128_z_flag( float128_le_quiet, syst_float128_le_quiet );
break;
#endif
#ifdef SYST_FLOAT128_LT_QUIET
case FLOAT128_LT_QUIET:
test_ab_float128_z_flag( float128_lt_quiet, syst_float128_lt_quiet );
break;
#endif
}
if ( ( errorStop && anyErrors ) || stop ) exitWithStatus();
 
}
 
void
testFunction(
uint8 functionCode, int8 roundingPrecisionIn, int8 roundingModeIn )
{
int8 roundingPrecision, roundingMode;
roundingPrecision = 32;
for (;;) {
 
if ( ! functions[ functionCode ].roundingPrecision ) {
roundingPrecision = 0;
}
else if ( roundingPrecisionIn ) {
roundingPrecision = roundingPrecisionIn;
}
for ( roundingMode = 1;
roundingMode < NUM_ROUNDINGMODES;
++roundingMode
)
{
if ( ! functions[ functionCode ].roundingMode ) {
roundingMode = 0;
}
else if ( roundingModeIn ) {
roundingMode = roundingModeIn;
}
testFunctionVariety(
functionCode, roundingPrecision, roundingMode );
if ( roundingModeIn || ! roundingMode )
break;
}
if ( roundingPrecisionIn || ! roundingPrecision )
break;
if ( roundingPrecision == 80 ) {
break;
}
else if ( roundingPrecision == 64 ) {
roundingPrecision = 80;
}
else if ( roundingPrecision == 32 ) {
roundingPrecision = 64;
}
}
}
 
/milieu.h
0,0 → 1,66
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
/*
-------------------------------------------------------------------------------
Include common integer types and flags.
-------------------------------------------------------------------------------
*/
#include "or1k-gcc.h"
 
/*
-------------------------------------------------------------------------------
If the `BITS64' macro is defined by the processor header file but the
version of SoftFloat being used/tested is the 32-bit one (`bits32'), the
`BITS64' macro must be undefined here.
-------------------------------------------------------------------------------
#undef BITS64
*/
 
/*
-------------------------------------------------------------------------------
The macro `LONG_DOUBLE_IS_FLOATX80' can be defined to indicate that the
C compiler supports the type `long double' as an extended double-precision
format. Alternatively, the macro `LONG_DOUBLE_IS_FLOAT128' can be defined
to indicate that `long double' is a quadruple-precision format. If neither
of these macros is defined, `long double' will be ignored.
-------------------------------------------------------------------------------
#define LONG_DOUBLE_IS_FLOATX80
*/
 
/*
-------------------------------------------------------------------------------
Symbolic Boolean literals.
-------------------------------------------------------------------------------
*/
enum {
FALSE = 0,
TRUE = 1
};
 
/systmodes.c
0,0 → 1,107
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
#include "milieu.h"
#include "systmodes.h"
#include "spr-defs.h"
 
// Rounding modes as used by softfloat, we use them here to
enum {
float_round_nearest_even = 0,
float_round_down = 1,
float_round_up = 2,
float_round_to_zero = 3
};
 
/*
-------------------------------------------------------------------------------
Sets the system's IEC/IEEE floating-point rounding mode. Also disables all
system exception traps.
-------------------------------------------------------------------------------
*/
void syst_float_set_rounding_mode( int8 roundingMode )
{
 
// Read the FPCSR
unsigned int spr = SPR_FPCSR;
unsigned int value;
// Read the SPR
asm("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr));
 
// Clear the current rounding mode
value &= ~SPR_FPCSR_RM;
 
// Extract the flags from OR1K's FPCSR, put into testfloat's flags format
switch(roundingMode)
{
case float_round_nearest_even:
value |= FPCSR_RM_RN;
break;
case float_round_down:
value |= FPCSR_RM_RIN;
break;
case float_round_up:
value |= FPCSR_RM_RIP;
break;
case float_round_to_zero:
value |= FPCSR_RM_RZ;
break;
default:
//printf("%s: Unknown rounding mode: 0x%x\n",__FUNCTION__,roundingMode);
// error!
break;
}
 
// Disable FPEE
value &= ~SPR_FPCSR_FPEE;
 
// Write value back to FPCSR
asm("l.mtspr\t\t%0,%1,0": : "r" (spr), "r" (value));
}
 
/*
-------------------------------------------------------------------------------
Sets the rounding precision of subsequent extended double-precision
operations. The `precision' argument should be one of 0, 32, 64, or 80.
If `precision' is 32, the rounding precision is set equivalent to single
precision; else if `precision' is 64, the rounding precision is set
equivalent to double precision; else the rounding precision is set to full
extended double precision.
-------------------------------------------------------------------------------
*/
void syst_float_set_rounding_precision( int8 precision )
{
 
//!!!code (possibly empty)
// Yes empty for OR1K 32-bit implementation - have no choice of rounding
// precision.
return;
 
}
 
/testFunction.h
0,0 → 1,139
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
enum {
INT32_TO_FLOAT32 = 1,
INT32_TO_FLOAT64,
INT32_TO_FLOATX80,
INT32_TO_FLOAT128,
INT64_TO_FLOAT32,
INT64_TO_FLOAT64,
INT64_TO_FLOATX80,
INT64_TO_FLOAT128,
FLOAT32_TO_INT32,
FLOAT32_TO_INT32_ROUND_TO_ZERO,
FLOAT32_TO_INT64,
FLOAT32_TO_INT64_ROUND_TO_ZERO,
FLOAT32_TO_FLOAT64,
FLOAT32_TO_FLOATX80,
FLOAT32_TO_FLOAT128,
FLOAT32_ROUND_TO_INT,
FLOAT32_ADD,
FLOAT32_SUB,
FLOAT32_MUL,
FLOAT32_DIV,
FLOAT32_REM,
FLOAT32_SQRT,
FLOAT32_EQ,
FLOAT32_LE,
FLOAT32_LT,
FLOAT32_EQ_SIGNALING,
FLOAT32_LE_QUIET,
FLOAT32_LT_QUIET,
FLOAT64_TO_INT32,
FLOAT64_TO_INT32_ROUND_TO_ZERO,
FLOAT64_TO_INT64,
FLOAT64_TO_INT64_ROUND_TO_ZERO,
FLOAT64_TO_FLOAT32,
FLOAT64_TO_FLOATX80,
FLOAT64_TO_FLOAT128,
FLOAT64_ROUND_TO_INT,
FLOAT64_ADD,
FLOAT64_SUB,
FLOAT64_MUL,
FLOAT64_DIV,
FLOAT64_REM,
FLOAT64_SQRT,
FLOAT64_EQ,
FLOAT64_LE,
FLOAT64_LT,
FLOAT64_EQ_SIGNALING,
FLOAT64_LE_QUIET,
FLOAT64_LT_QUIET,
FLOATX80_TO_INT32,
FLOATX80_TO_INT32_ROUND_TO_ZERO,
FLOATX80_TO_INT64,
FLOATX80_TO_INT64_ROUND_TO_ZERO,
FLOATX80_TO_FLOAT32,
FLOATX80_TO_FLOAT64,
FLOATX80_TO_FLOAT128,
FLOATX80_ROUND_TO_INT,
FLOATX80_ADD,
FLOATX80_SUB,
FLOATX80_MUL,
FLOATX80_DIV,
FLOATX80_REM,
FLOATX80_SQRT,
FLOATX80_EQ,
FLOATX80_LE,
FLOATX80_LT,
FLOATX80_EQ_SIGNALING,
FLOATX80_LE_QUIET,
FLOATX80_LT_QUIET,
FLOAT128_TO_INT32,
FLOAT128_TO_INT32_ROUND_TO_ZERO,
FLOAT128_TO_INT64,
FLOAT128_TO_INT64_ROUND_TO_ZERO,
FLOAT128_TO_FLOAT32,
FLOAT128_TO_FLOAT64,
FLOAT128_TO_FLOATX80,
FLOAT128_ROUND_TO_INT,
FLOAT128_ADD,
FLOAT128_SUB,
FLOAT128_MUL,
FLOAT128_DIV,
FLOAT128_REM,
FLOAT128_SQRT,
FLOAT128_EQ,
FLOAT128_LE,
FLOAT128_LT,
FLOAT128_EQ_SIGNALING,
FLOAT128_LE_QUIET,
FLOAT128_LT_QUIET,
NUM_FUNCTIONS
};
 
typedef struct {
char *name;
int8 numInputs;
flag roundingPrecision, roundingMode;
} functionT;
extern const functionT functions[ NUM_FUNCTIONS ];
extern const flag functionExists[ NUM_FUNCTIONS ];
 
enum {
ROUND_NEAREST_EVEN = 1,
ROUND_TO_ZERO,
ROUND_DOWN,
ROUND_UP,
NUM_ROUNDINGMODES
};
 
void testFunction( uint8, int8, int8 );
 
/testLoops.c
0,0 → 1,2735
 
/*
===============================================================================
 
This C source file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
/*
#include <stdlib.h>
#include <stdio.h>
*/
#include "support.h" // OR1k support C library
#include "milieu.h"
#include "softfloat.h"
#include "testCases.h"
#include "writeHex.h"
#include "testLoops.h"
 
volatile flag stop = FALSE;
 
char *trueName, *testName;
flag forever, errorStop;
uint32 maxErrorCount = 0;
flag checkNaNs = FALSE;
int8 *trueFlagsPtr;
int8 ( *testFlagsFunctionPtr )( void );
char *functionName;
char *roundingPrecisionName, *roundingModeName, *tininessModeName;
flag anyErrors = FALSE;
 
void
writeFunctionName( /* FILE *stream */ )
{
 
printf( functionName/*, stream */ );
if ( roundingModeName ) {
if ( roundingPrecisionName ) {
printf( ", precision "/*, stream */ );
printf( roundingPrecisionName/*, stream */ );
}
printf( ", rounding "/*, stream */ );
printf( roundingModeName/*, stream */ );
if ( tininessModeName ) {
printf( ", tininess "/*, stream */ );
printf( tininessModeName/*, stream */ );
printf( " rounding"/*, stream */ );
}
}
 
}
 
void
exitWithStatus( void )
{
 
exit( anyErrors ? /*EXIT_FAILURE */ 0x1 : /* EXIT_SUCCESS */ 0 );
 
}
 
static uint32 tenthousandsCount, errorCount = 0;
 
static void
writeTestsTotal( void )
{
 
if ( forever ) {
printf( "Unbounded tests.\n"/*, stderr */ );
}
else {
printf( "\r%d tests total.\n", testCases_total );
}
 
}
 
static void
writeTestsPerformed( int16 count )
{
 
if ( tenthousandsCount ) {
printf(
"\r%d%04d tests performed", tenthousandsCount, count );
}
else {
printf( "\r%d tests performed", count );
}
if ( errorCount ) {
printf(
"; %d error%s found.\n",
errorCount,
( errorCount == 1 ) ? "" : "s"
);
}
else {
printf( ".\n"/*, stderr */ );
printf( "No errors found in "/*, stdout*/ );
writeFunctionName( /*stdout */ );
printf( ".\n"/*, stdout*/ );
//fflush( stdout );
}
 
}
 
static void
checkEarlyExit( void )
{
 
++tenthousandsCount;
if ( stop ) {
writeTestsPerformed( 0 );
exitWithStatus();
}
printf( "\r%3d0000", tenthousandsCount );
 
}
 
static void
writeErrorFound( int16 count )
{
 
putchar( '\r'/*, stderr */ );
if ( errorCount == 1 ) {
printf( "Errors found in "/*, stdout*/ );
writeFunctionName( /*stdout*/ );
printf( ":\n"/*, stdout*/ );
}
if ( stop ) {
writeTestsPerformed( count );
exitWithStatus();
}
anyErrors = TRUE;
 
}
 
INLINE void
writeInput_a_int32( void )
{
 
writeHex_bits32( testCases_a_int32/*, stdout*/ );
 
}
 
#ifdef BITS64
 
INLINE void
writeInput_a_int64( void )
{
 
writeHex_bits64( testCases_a_int64/*, stdout*/ );
 
}
 
#endif
 
INLINE void
writeInput_a_float32( void )
{
 
writeHex_float32( testCases_a_float32/*, stdout*/ );
 
}
 
static void
writeInputs_ab_float32( void )
{
 
writeHex_float32( testCases_a_float32/*, stdout*/ );
printf( " "/*, stdout*/ );
writeHex_float32( testCases_b_float32/*, stdout*/ );
 
}
 
INLINE void
writeInput_a_float64( void )
{
 
writeHex_float64( testCases_a_float64/*, stdout*/ );
 
}
 
static void
writeInputs_ab_float64( void )
{
 
writeHex_float64( testCases_a_float64/*, stdout*/ );
printf( " "/*, stdout*/ );
writeHex_float64( testCases_b_float64/*, stdout*/ );
 
}
 
#ifdef FLOATX80
 
INLINE void
writeInput_a_floatx80( void )
{
 
writeHex_floatx80( testCases_a_floatx80/*, stdout*/ );
 
}
 
static void
writeInputs_ab_floatx80( void )
{
 
writeHex_floatx80( testCases_a_floatx80/*, stdout*/ );
printf( " "/*, stdout*/ );
writeHex_floatx80( testCases_b_floatx80/*, stdout*/ );
 
}
 
#endif
 
#ifdef FLOAT128
 
INLINE void
writeInput_a_float128( void )
{
 
writeHex_float128( testCases_a_float128/*, stdout*/ );
 
}
 
static void
writeInputs_ab_float128( void )
{
 
writeHex_float128( testCases_a_float128/*, stdout*/ );
printf( " "/*, stdout*/ );
writeHex_float128( testCases_b_float128/*, stdout*/ );
 
}
 
#endif
 
static void
writeOutputs_z_flag(
flag trueZ, uint8 trueFlags, flag testZ, uint8 testFlags )
{
 
printf( trueName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_flag( trueZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( trueFlags/*, stdout*/ );
printf( " "/*, stdout*/ );
printf( testName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_flag( testZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( testFlags/*, stdout*/ );
putchar( '\n'/*, stdout*/ );
 
}
 
static void
writeOutputs_z_int32(
int32 trueZ, uint8 trueFlags, int32 testZ, uint8 testFlags )
{
 
printf( trueName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_bits32( trueZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( trueFlags/*, stdout*/ );
printf( " "/*, stdout*/ );
printf( testName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_bits32( testZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( testFlags/*, stdout*/ );
putchar( '\n'/*, stdout*/ );
 
}
 
#ifdef BITS64
 
static void
writeOutputs_z_int64(
int64 trueZ, uint8 trueFlags, int64 testZ, uint8 testFlags )
{
 
printf( trueName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_bits64( trueZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( trueFlags/*, stdout*/ );
printf( " "/*, stdout*/ );
printf( testName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_bits64( testZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( testFlags/*, stdout*/ );
putchar( '\n'/*, stdout*/ );
 
}
 
#endif
 
static void
writeOutputs_z_float32(
float32 trueZ, uint8 trueFlags, float32 testZ, uint8 testFlags )
{
 
printf( trueName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_float32( trueZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( trueFlags/*, stdout*/ );
printf( " "/*, stdout*/ );
printf( testName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_float32( testZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( testFlags/*, stdout*/ );
putchar( '\n'/*, stdout*/ );
 
}
 
static void
writeOutputs_z_float64(
float64 trueZ, uint8 trueFlags, float64 testZ, uint8 testFlags )
{
 
printf( trueName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_float64( trueZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( trueFlags/*, stdout*/ );
printf( " "/*, stdout*/ );
printf( testName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_float64( testZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( testFlags/*, stdout*/ );
putchar( '\n'/*, stdout*/ );
 
}
 
#ifdef FLOATX80
 
static void
writeOutputs_z_floatx80(
floatx80 trueZ, uint8 trueFlags, floatx80 testZ, uint8 testFlags )
{
 
printf( trueName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_floatx80( trueZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( trueFlags/*, stdout*/ );
printf( " "/*, stdout*/ );
printf( testName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_floatx80( testZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( testFlags/*, stdout*/ );
putchar( '\n'/*, stdout*/ );
 
}
 
#endif
 
#ifdef FLOAT128
 
static void
writeOutputs_z_float128(
float128 trueZ, uint8 trueFlags, float128 testZ, uint8 testFlags )
{
 
printf( trueName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_float128( trueZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( trueFlags/*, stdout*/ );
printf( "\n\t"/*, stdout*/ );
printf( testName/*, stdout*/ );
printf( ": "/*, stdout*/ );
writeHex_float128( testZ/*, stdout*/ );
putchar( ' '/*, stdout*/ );
writeHex_float_flags( testFlags/*, stdout*/ );
putchar( '\n'/*, stdout*/ );
 
}
 
#endif
 
INLINE flag float32_isNaN( float32 a )
{
 
return 0x7F800000 < ( a & 0x7FFFFFFF );
 
}
 
#ifdef BITS64
 
INLINE flag float64_same( float64 a, float64 b )
{
 
return a == b;
 
}
 
INLINE flag float64_isNaN( float64 a )
{
 
return LIT64( 0x7FF0000000000000 ) < ( a & LIT64( 0x7FFFFFFFFFFFFFFF ) );
 
}
 
#else
 
INLINE flag float64_same( float64 a, float64 b )
{
 
return ( a.high == b.high ) && ( a.low == b.low );
 
}
 
INLINE flag float64_isNaN( float64 a )
{
bits32 absAHigh;
 
absAHigh = a.high & 0x7FFFFFFF;
return
( 0x7FF00000 < absAHigh ) || ( ( absAHigh == 0x7FF00000 ) && a.low );
 
}
 
#endif
 
#ifdef FLOATX80
 
INLINE flag floatx80_same( floatx80 a, floatx80 b )
{
 
return ( a.high == b.high ) && ( a.low == b.low );
 
}
 
INLINE flag floatx80_isNaN( floatx80 a )
{
 
return ( ( a.high & 0x7FFF ) == 0x7FFF ) && a.low;
 
}
 
#endif
 
#ifdef FLOAT128
 
INLINE flag float128_same( float128 a, float128 b )
{
 
return ( a.high == b.high ) && ( a.low == b.low );
 
}
 
INLINE flag float128_isNaN( float128 a )
{
bits64 absAHigh;
 
absAHigh = a.high & LIT64( 0x7FFFFFFFFFFFFFFF );
return
( LIT64( 0x7FFF000000000000 ) < absAHigh )
|| ( ( absAHigh == LIT64( 0x7FFF000000000000 ) ) && a.low );
 
}
 
#endif
 
void
test_a_int32_z_float32(
float32 trueFunction( int32 ), float32 testFunction( int32 ) )
{
int16 count;
float32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_int32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_int32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_int32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float32_isNaN( trueZ )
&& float32_isNaN( testZ )
&& ! float32_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_int32();
printf( " "/*, stdout*/ );
writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
void
test_a_int32_z_float64(
float64 trueFunction( int32 ), float64 testFunction( int32 ) )
{
int16 count;
float64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_int32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_int32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_int32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float64_isNaN( trueZ )
&& float64_isNaN( testZ )
&& ! float64_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_int32();
printf( " "/*, stdout*/ );
writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef FLOATX80
 
void
test_a_int32_z_floatx80(
floatx80 trueFunction( int32 ), floatx80 testFunction( int32 ) )
{
int16 count;
floatx80 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_int32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_int32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_int32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& floatx80_isNaN( trueZ )
&& floatx80_isNaN( testZ )
&& ! floatx80_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_int32();
printf( " "/*, stdout*/ );
writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
#ifdef FLOAT128
 
void
test_a_int32_z_float128(
float128 trueFunction( int32 ), float128 testFunction( int32 ) )
{
int16 count;
float128 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_int32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_int32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_int32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float128_isNaN( trueZ )
&& float128_isNaN( testZ )
&& ! float128_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_int32();
printf( "\n\t"/*, stdout*/ );
writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
#ifdef BITS64
 
void
test_a_int64_z_float32(
float32 trueFunction( int64 ), float32 testFunction( int64 ) )
{
int16 count;
float32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_int64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_int64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_int64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float32_isNaN( trueZ )
&& float32_isNaN( testZ )
&& ! float32_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_int64();
printf( " "/*, stdout*/ );
writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
void
test_a_int64_z_float64(
float64 trueFunction( int64 ), float64 testFunction( int64 ) )
{
int16 count;
float64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_int64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_int64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_int64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float64_isNaN( trueZ )
&& float64_isNaN( testZ )
&& ! float64_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_int64();
printf( " "/*, stdout*/ );
writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef FLOATX80
 
void
test_a_int64_z_floatx80(
floatx80 trueFunction( int64 ), floatx80 testFunction( int64 ) )
{
int16 count;
floatx80 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_int64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_int64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_int64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& floatx80_isNaN( trueZ )
&& floatx80_isNaN( testZ )
&& ! floatx80_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_int64();
printf( " "/*, stdout*/ );
writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
#ifdef FLOAT128
 
void
test_a_int64_z_float128(
float128 trueFunction( int64 ), float128 testFunction( int64 ) )
{
int16 count;
float128 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_int64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_int64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_int64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float128_isNaN( trueZ )
&& float128_isNaN( testZ )
&& ! float128_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_int64();
printf( "\n\t"/*, stdout*/ );
writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
#endif
 
void
test_a_float32_z_int32(
int32 trueFunction( float32 ), int32 testFunction( float32 ) )
{
int16 count;
int32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float32_is_signaling_nan( testCases_a_float32 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ == 0x7FFFFFFF )
&& ( ( testZ == 0x7FFFFFFF )
|| ( testZ == (sbits32) 0x80000000 ) )
&& ( trueFlags == float_flag_invalid )
&& ( testFlags == float_flag_invalid )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float32();
printf( " "/*, stdout*/ );
writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef BITS64
 
void
test_a_float32_z_int64(
int64 trueFunction( float32 ), int64 testFunction( float32 ) )
{
int16 count;
int64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float32_is_signaling_nan( testCases_a_float32 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
&& ( ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
|| ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
&& ( trueFlags == float_flag_invalid )
&& ( testFlags == float_flag_invalid )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float32();
printf( " "/*, stdout*/ );
writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
void
test_a_float32_z_float64(
float64 trueFunction( float32 ), float64 testFunction( float32 ) )
{
int16 count;
float64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float32_is_signaling_nan( testCases_a_float32 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float64_isNaN( trueZ )
&& float64_isNaN( testZ )
&& ! float64_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float32();
printf( " "/*, stdout*/ );
writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef FLOATX80
 
void
test_a_float32_z_floatx80(
floatx80 trueFunction( float32 ), floatx80 testFunction( float32 ) )
{
int16 count;
floatx80 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float32_is_signaling_nan( testCases_a_float32 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& floatx80_isNaN( trueZ )
&& floatx80_isNaN( testZ )
&& ! floatx80_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float32();
printf( "\n\t"/*, stdout*/ );
writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
#ifdef FLOAT128
 
void
test_a_float32_z_float128(
float128 trueFunction( float32 ), float128 testFunction( float32 ) )
{
int16 count;
float128 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float32_is_signaling_nan( testCases_a_float32 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float128_isNaN( trueZ )
&& float128_isNaN( testZ )
&& ! float128_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float32();
printf( "\n\t"/*, stdout*/ );
writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
void
test_az_float32(
float32 trueFunction( float32 ), float32 testFunction( float32 ) )
{
int16 count;
float32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float32_is_signaling_nan( testCases_a_float32 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float32_isNaN( trueZ )
&& float32_isNaN( testZ )
&& ! float32_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float32();
printf( " "/*, stdout*/ );
writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
void
test_ab_float32_z_flag(
flag trueFunction( float32, float32 ),
flag testFunction( float32, float32 )
)
{
int16 count;
flag trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_ab_float32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float32, testCases_b_float32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float32, testCases_b_float32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& ( float32_is_signaling_nan( testCases_a_float32 )
|| float32_is_signaling_nan( testCases_b_float32 ) )
) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
++errorCount;
writeErrorFound( 10000 - count );
writeInputs_ab_float32();
puts( " "/*, stdout*/ );
writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
return;
 
}
 
void
test_abz_float32(
float32 trueFunction( float32, float32 ),
float32 testFunction( float32, float32 )
)
{
int16 count;
float32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_ab_float32 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float32, testCases_b_float32 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float32, testCases_b_float32 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& ( float32_is_signaling_nan( testCases_a_float32 )
|| float32_is_signaling_nan( testCases_b_float32 ) )
) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float32_isNaN( trueZ )
&& float32_isNaN( testZ )
&& ! float32_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInputs_ab_float32();
puts( " "/*, stdout*/ );
writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
return;
 
}
 
void
test_a_float64_z_int32(
int32 trueFunction( float64 ), int32 testFunction( float64 ) )
{
int16 count;
int32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float64_is_signaling_nan( testCases_a_float64 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ == 0x7FFFFFFF )
&& ( ( testZ == 0x7FFFFFFF )
|| ( testZ == (sbits32) 0x80000000 ) )
&& ( trueFlags == float_flag_invalid )
&& ( testFlags == float_flag_invalid )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float64();
puts( " "/*, stdout*/ );
writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef BITS64
 
void
test_a_float64_z_int64(
int64 trueFunction( float64 ), int64 testFunction( float64 ) )
{
int16 count;
int64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float64_is_signaling_nan( testCases_a_float64 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
&& ( ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
|| ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
&& ( trueFlags == float_flag_invalid )
&& ( testFlags == float_flag_invalid )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float64();
puts( " "/*, stdout*/ );
writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
void
test_a_float64_z_float32(
float32 trueFunction( float64 ), float32 testFunction( float64 ) )
{
int16 count;
float32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float64_is_signaling_nan( testCases_a_float64 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float32_isNaN( trueZ )
&& float32_isNaN( testZ )
&& ! float32_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float64();
puts( " "/*, stdout*/ );
writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef FLOATX80
 
void
test_a_float64_z_floatx80(
floatx80 trueFunction( float64 ), floatx80 testFunction( float64 ) )
{
int16 count;
floatx80 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float64_is_signaling_nan( testCases_a_float64 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& floatx80_isNaN( trueZ )
&& floatx80_isNaN( testZ )
&& ! floatx80_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float64();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
#ifdef FLOAT128
 
void
test_a_float64_z_float128(
float128 trueFunction( float64 ), float128 testFunction( float64 ) )
{
int16 count;
float128 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float64_is_signaling_nan( testCases_a_float64 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float128_isNaN( trueZ )
&& float128_isNaN( testZ )
&& ! float128_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float64();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
void
test_az_float64(
float64 trueFunction( float64 ), float64 testFunction( float64 ) )
{
int16 count;
float64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float64_is_signaling_nan( testCases_a_float64 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float64_isNaN( trueZ )
&& float64_isNaN( testZ )
&& ! float64_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float64();
puts( " "/*, stdout*/ );
writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
void
test_ab_float64_z_flag(
flag trueFunction( float64, float64 ),
flag testFunction( float64, float64 )
)
{
int16 count;
flag trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_ab_float64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float64, testCases_b_float64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float64, testCases_b_float64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& ( float64_is_signaling_nan( testCases_a_float64 )
|| float64_is_signaling_nan( testCases_b_float64 ) )
) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
++errorCount;
writeErrorFound( 10000 - count );
writeInputs_ab_float64();
puts( " "/*, stdout*/ );
writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
return;
 
}
 
void
test_abz_float64(
float64 trueFunction( float64, float64 ),
float64 testFunction( float64, float64 )
)
{
int16 count;
float64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_ab_float64 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float64, testCases_b_float64 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float64, testCases_b_float64 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& ( float64_is_signaling_nan( testCases_a_float64 )
|| float64_is_signaling_nan( testCases_b_float64 ) )
) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float64_isNaN( trueZ )
&& float64_isNaN( testZ )
&& ! float64_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInputs_ab_float64();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
return;
 
}
 
#ifdef FLOATX80
 
void
test_a_floatx80_z_int32(
int32 trueFunction( floatx80 ), int32 testFunction( floatx80 ) )
{
int16 count;
int32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_floatx80 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_floatx80 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_floatx80 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ == 0x7FFFFFFF )
&& ( ( testZ == 0x7FFFFFFF )
|| ( testZ == (sbits32) 0x80000000 ) )
&& ( trueFlags == float_flag_invalid )
&& ( testFlags == float_flag_invalid )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_floatx80();
puts( " "/*, stdout*/ );
writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef BITS64
 
void
test_a_floatx80_z_int64(
int64 trueFunction( floatx80 ), int64 testFunction( floatx80 ) )
{
int16 count;
int64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_floatx80 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_floatx80 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_floatx80 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
&& ( ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
|| ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
&& ( trueFlags == float_flag_invalid )
&& ( testFlags == float_flag_invalid )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_floatx80();
puts( " "/*, stdout*/ );
writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
void
test_a_floatx80_z_float32(
float32 trueFunction( floatx80 ), float32 testFunction( floatx80 ) )
{
int16 count;
float32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_floatx80 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_floatx80 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_floatx80 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float32_isNaN( trueZ )
&& float32_isNaN( testZ )
&& ! float32_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_floatx80();
puts( " "/*, stdout*/ );
writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
void
test_a_floatx80_z_float64(
float64 trueFunction( floatx80 ), float64 testFunction( floatx80 ) )
{
int16 count;
float64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_floatx80 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_floatx80 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_floatx80 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float64_isNaN( trueZ )
&& float64_isNaN( testZ )
&& ! float64_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_floatx80();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef FLOAT128
 
void
test_a_floatx80_z_float128(
float128 trueFunction( floatx80 ), float128 testFunction( floatx80 ) )
{
int16 count;
float128 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_floatx80 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_floatx80 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_floatx80 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float128_isNaN( trueZ )
&& float128_isNaN( testZ )
&& ! float128_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_floatx80();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
void
test_az_floatx80(
floatx80 trueFunction( floatx80 ), floatx80 testFunction( floatx80 ) )
{
int16 count;
floatx80 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_floatx80 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_floatx80 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_floatx80 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& floatx80_isNaN( trueZ )
&& floatx80_isNaN( testZ )
&& ! floatx80_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_floatx80();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
void
test_ab_floatx80_z_flag(
flag trueFunction( floatx80, floatx80 ),
flag testFunction( floatx80, floatx80 )
)
{
int16 count;
flag trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_ab_floatx80 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_floatx80, testCases_b_floatx80 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_floatx80, testCases_b_floatx80 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& ( floatx80_is_signaling_nan( testCases_a_floatx80 )
|| floatx80_is_signaling_nan( testCases_b_floatx80 ) )
) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
++errorCount;
writeErrorFound( 10000 - count );
writeInputs_ab_floatx80();
puts( " "/*, stdout*/ );
writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
return;
 
}
 
void
test_abz_floatx80(
floatx80 trueFunction( floatx80, floatx80 ),
floatx80 testFunction( floatx80, floatx80 )
)
{
int16 count;
floatx80 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_ab_floatx80 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_floatx80, testCases_b_floatx80 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_floatx80, testCases_b_floatx80 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& ( floatx80_is_signaling_nan( testCases_a_floatx80 )
|| floatx80_is_signaling_nan( testCases_b_floatx80 ) )
) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& floatx80_isNaN( trueZ )
&& floatx80_isNaN( testZ )
&& ! floatx80_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInputs_ab_floatx80();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
return;
 
}
 
#endif
 
#ifdef FLOAT128
 
void
test_a_float128_z_int32(
int32 trueFunction( float128 ), int32 testFunction( float128 ) )
{
int16 count;
int32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float128 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float128 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float128 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float128_is_signaling_nan( testCases_a_float128 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ == 0x7FFFFFFF )
&& ( ( testZ == 0x7FFFFFFF )
|| ( testZ == (sbits32) 0x80000000 ) )
&& ( trueFlags == float_flag_invalid )
&& ( testFlags == float_flag_invalid )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float128();
puts( " "/*, stdout*/ );
writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef BITS64
 
void
test_a_float128_z_int64(
int64 trueFunction( float128 ), int64 testFunction( float128 ) )
{
int16 count;
int64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float128 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float128 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float128 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float128_is_signaling_nan( testCases_a_float128 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
&& ( ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
|| ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
&& ( trueFlags == float_flag_invalid )
&& ( testFlags == float_flag_invalid )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float128();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
void
test_a_float128_z_float32(
float32 trueFunction( float128 ), float32 testFunction( float128 ) )
{
int16 count;
float32 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float128 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float128 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float128 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float128_is_signaling_nan( testCases_a_float128 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float32_isNaN( trueZ )
&& float32_isNaN( testZ )
&& ! float32_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float128();
puts( " "/*, stdout*/ );
writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
void
test_a_float128_z_float64(
float64 trueFunction( float128 ), float64 testFunction( float128 ) )
{
int16 count;
float64 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float128 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float128 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float128 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float128_is_signaling_nan( testCases_a_float128 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float64_isNaN( trueZ )
&& float64_isNaN( testZ )
&& ! float64_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float128();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#ifdef FLOATX80
 
void
test_a_float128_z_floatx80(
floatx80 trueFunction( float128 ), floatx80 testFunction( float128 ) )
{
int16 count;
floatx80 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float128 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float128 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float128 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float128_is_signaling_nan( testCases_a_float128 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& floatx80_isNaN( trueZ )
&& floatx80_isNaN( testZ )
&& ! floatx80_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float128();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
#endif
 
void
test_az_float128(
float128 trueFunction( float128 ), float128 testFunction( float128 ) )
{
int16 count;
float128 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_a_float128 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float128 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float128 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& float128_is_signaling_nan( testCases_a_float128 ) ) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float128_isNaN( trueZ )
&& float128_isNaN( testZ )
&& ! float128_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInput_a_float128();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
 
}
 
void
test_ab_float128_z_flag(
flag trueFunction( float128, float128 ),
flag testFunction( float128, float128 )
)
{
int16 count;
flag trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_ab_float128 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float128, testCases_b_float128 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float128, testCases_b_float128 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& ( float128_is_signaling_nan( testCases_a_float128 )
|| float128_is_signaling_nan( testCases_b_float128 ) )
) {
trueFlags |= float_flag_invalid;
}
if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
++errorCount;
writeErrorFound( 10000 - count );
writeInputs_ab_float128();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
return;
 
}
 
void
test_abz_float128(
float128 trueFunction( float128, float128 ),
float128 testFunction( float128, float128 )
)
{
int16 count;
float128 trueZ, testZ;
uint8 trueFlags, testFlags;
 
errorCount = 0;
tenthousandsCount = 0;
count = 10000;
testCases_initSequence( testCases_sequence_ab_float128 );
writeTestsTotal();
while ( ! testCases_done || forever ) {
testCases_next();
*trueFlagsPtr = 0;
trueZ = trueFunction( testCases_a_float128, testCases_b_float128 );
trueFlags = *trueFlagsPtr;
(void) testFlagsFunctionPtr();
testZ = testFunction( testCases_a_float128, testCases_b_float128 );
testFlags = testFlagsFunctionPtr();
--count;
if ( count == 0 ) {
checkEarlyExit();
count = 10000;
}
if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
if ( ! checkNaNs
&& ( float128_is_signaling_nan( testCases_a_float128 )
|| float128_is_signaling_nan( testCases_b_float128 ) )
) {
trueFlags |= float_flag_invalid;
}
if ( ! checkNaNs
&& float128_isNaN( trueZ )
&& float128_isNaN( testZ )
&& ! float128_is_signaling_nan( testZ )
&& ( trueFlags == testFlags )
) {
/* no problem */
}
else {
++errorCount;
writeErrorFound( 10000 - count );
writeInputs_ab_float128();
puts( "\n\t"/*, stdout*/ );
writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
//fflush( stdout );
if ( errorCount == maxErrorCount ) goto exit;
}
}
}
exit:
writeTestsPerformed( 10000 - count );
return;
 
}
 
#endif
 
/systfloat.h
0,0 → 1,72
 
/*
===============================================================================
 
This C header file is part of TestFloat, Release 2a, a package of programs
for testing the correctness of floating-point arithmetic complying to the
IEC/IEEE Standard for Floating-Point.
 
Written by John R. Hauser. More information is available through the Web
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 
Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
 
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
 
===============================================================================
*/
 
/*
-------------------------------------------------------------------------------
The following macros are defined to indicate that the corresponding
functions exist.
-------------------------------------------------------------------------------
*/
#define SYST_INT32_TO_FLOAT32
#define SYST_FLOAT32_TO_INT32
#define SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
//#define SYST_FLOAT32_ROUND_TO_INT
#define SYST_FLOAT32_ADD
#define SYST_FLOAT32_SUB
#define SYST_FLOAT32_MUL
#define SYST_FLOAT32_DIV
#define SYST_FLOAT32_EQ
#define SYST_FLOAT32_LE
#define SYST_FLOAT32_LT
 
 
 
 
/*
-------------------------------------------------------------------------------
System function declarations. (Some of these functions may not exist.)
-------------------------------------------------------------------------------
*/
float32 syst_int32_to_float32( int32 );
int32 syst_float32_to_int32( float32 );
int32 syst_float32_to_int32_round_to_zero( float32 );
float32 syst_float32_round_to_int( float32 );
float32 syst_float32_add( float32, float32 );
float32 syst_float32_sub( float32, float32 );
float32 syst_float32_mul( float32, float32 );
float32 syst_float32_div( float32, float32 );
float32 syst_float32_rem( float32, float32 );
flag syst_float32_eq( float32, float32 );
flag syst_float32_le( float32, float32 );
flag syst_float32_lt( float32, float32 );
flag syst_float32_eq_signaling( float32, float32 );
flag syst_float32_le_quiet( float32, float32 );
flag syst_float32_lt_quiet( float32, float32 );
 
 
/or1k-gcc.h
0,0 → 1,85
/*
Modified for use with or1ksim's testsuite.
 
Contributor Julius Baxter <julius.baxter@orsoc.se>
*/
/*
-------------------------------------------------------------------------------
One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
-------------------------------------------------------------------------------
*/
#define BIGENDIAN
 
/*
-------------------------------------------------------------------------------
The macro `BITS64' can be defined to indicate that 64-bit integer types are
supported by the compiler.
-------------------------------------------------------------------------------
*/
#define BITS64
 
/*
-------------------------------------------------------------------------------
Each of the following `typedef's defines the most convenient type that holds
integers of at least as many bits as specified. For example, `uint8' should
be the most convenient type that can hold unsigned integers of as many as
8 bits. The `flag' type must be able to hold either a 0 or 1. For most
implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
to the same as `int'.
-------------------------------------------------------------------------------
*/
typedef char flag;
typedef unsigned char uint8;
typedef signed char int8;
typedef int uint16;
typedef int int16;
typedef unsigned int uint32;
typedef signed int int32;
#ifdef BITS64
typedef unsigned long long int uint64;
typedef signed long long int int64;
#endif
 
/*
-------------------------------------------------------------------------------
Each of the following `typedef's defines a type that holds integers
of _exactly_ the number of bits specified. For instance, for most
implementation of C, `bits16' and `sbits16' should be `typedef'ed to
`unsigned short int' and `signed short int' (or `short int'), respectively.
-------------------------------------------------------------------------------
*/
typedef unsigned char bits8;
typedef signed char sbits8;
typedef unsigned short int bits16;
typedef signed short int sbits16;
typedef unsigned int bits32;
typedef signed int sbits32;
#ifdef BITS64
typedef unsigned long long int bits64;
typedef signed long long int sbits64;
#endif
 
#ifdef BITS64
/*
-------------------------------------------------------------------------------
The `LIT64' macro takes as its argument a textual integer literal and
if necessary ``marks'' the literal as having a 64-bit integer type.
For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
appended with the letters `LL' standing for `long long', which is `gcc's
name for the 64-bit integer type. Some compilers may allow `LIT64' to be
defined as the identity macro: `#define LIT64( a ) a'.
-------------------------------------------------------------------------------
*/
#define LIT64( a ) a##LL
#endif
 
/*
-------------------------------------------------------------------------------
The macro `INLINE' can be used before functions that should be inlined. If
a compiler does not support explicit inlining, this macro should be defined
to be `static'.
-------------------------------------------------------------------------------
*/
//#define INLINE extern inline
#define INLINE static
 
/README
0,0 → 1,47
TestFloat software tests for floating point operations
 
From http://www.jhauser.us/arithmetic/TestFloat.html
 
TestFloat is a program for testing whether a computer's floating-point
conforms to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
TestFloat works by comparing the behavior of the machine's floating-point
with that of the SoftFloat software implementation of floating-point.
 
At present only the single precision floating point capability of the software
is used to test the OpenRISC's FPU.
 
The main loop of the applications in TestFloat have been modified so they do
not rely on input when executed, rather are hard-coded to run all the tests
they possibly can.
 
All of the output functions (fputs, putc, fprintf) have been replaced with
versions available in the OR1K support C library.
 
The software included here also includes the SoftFloat library, which is
is required to test the hardware FPU.
 
See http://www.jhauser.us/arithmetic/SoftFloat.html for more information on
SoftFloat.
 
The or1ksim simulator actually implements its single precision floating point
using functions from SoftFloat (see the softfloat/ path in the or1ksim project)
so potentially any non-standard behavior of the floating point unit in or1ksim
will not be picked up by this test (as TestFloat uses SoftFloat itself to check
against the hardware/system results.) However, TestFloat comes with a different
implementation of the IEEE 754 compliant conversion and arithmetic functions to
test SoftFloat against, hopefully picking up any inconsistencies that exist.
 
Note that the bits64 version of SoftFloat's library is included here. It is
not a problem for all of the current OR1K GCC implementations to handle 64-bit
data types.
 
The file layout of SoftFloat and TestFloat, in their distributions, has been
discarded and all the required files have been included in this path.
 
testfloat is run during the standard check that can be run after compilation.
By default only the testfloat program will be run (not testsoftfloat).
testsoftfloat will, actually, be compiled and be under
testsuite/test-code-or1k/testfloat and can be run from where if desired.
 
 
Julius Baxter, August 3 2010
/Makefile.am
0,0 → 1,71
# Makefile.am for or1ksim testsuite CPU test program: testsoftfloat, testfloat
 
# Copyright (C) ORSoC AB, 2010
 
# Contributor Julius Baxter <julius.baxter@orsoc.se>
 
# This file is part of OpenRISC 1000 Architectural Simulator.
 
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
 
# This program 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 General Public License for
# more details.
 
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http:#www.gnu.org/licenses/>. */
 
# -----------------------------------------------------------------------------
# This code is commented throughout for use with Doxygen.
# -----------------------------------------------------------------------------
 
 
# A test program of the OR1K Ethernet
check_PROGRAMS = testsoftfloat testfloat
 
common_testfloat_sources = milieu.h \
or1k-gcc.h \
fail.h \
fail.c \
random.h \
random.c \
writeHex.h \
writeHex.c \
softfloat.h \
softfloat.c \
testCases.h \
testCases.c \
testLoops.h \
testLoops.c
 
testsoftfloat_SOURCES = $(common_testfloat_sources) \
slowfloat.h \
slowfloat.c \
testsoftfloat.c
 
testsoftfloat_CFLAGS = -O3
testsoftfloat_LDFLAGS = -T$(srcdir)/../default.ld -lgcc
 
testsoftfloat_LDADD = ../except/except.lo \
../support/libsupport.la
 
testfloat_SOURCES = $(common_testfloat_sources) \
systmodes.h \
systmodes.c \
systflags.h \
systflags.c \
systfloat.h \
systfloat.S \
testFunction.h \
testFunction.c \
testfloat.c
testfloat_CFLAGS = -O2
testfloat_LDFLAGS = -T$(srcdir)/../default.ld -lgcc
 
testfloat_LDADD = ../except/except.lo \
../support/libsupport.la
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.