URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
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 |
|