ext: Include libfputils
This changeset includes libfputils from revision bbf0d61d75. This library can be used to convert to and from 80-bit floats and query the type of an 80-bit float, which is needed to support the x87 FPU.
This commit is contained in:
parent
3af2d8eab0
commit
d3937f3b37
20 changed files with 4051 additions and 0 deletions
|
@ -1110,6 +1110,10 @@ main.SConscript('ext/gzstream/SConscript',
|
|||
main.SConscript('ext/libfdt/SConscript',
|
||||
variant_dir = joinpath(build_root, 'libfdt'))
|
||||
|
||||
# fputils build is shared across all configs in the build root.
|
||||
main.SConscript('ext/fputils/SConscript',
|
||||
variant_dir = joinpath(build_root, 'fputils'))
|
||||
|
||||
###################################################
|
||||
#
|
||||
# This function is used to set up a directory with switching headers
|
||||
|
|
33
ext/fputils/.gitignore
vendored
Normal file
33
ext/fputils/.gitignore
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
/tests/Makefile
|
||||
/tests/Makefile.in
|
||||
/tests/fp80_cvfd
|
||||
/tests/fp80_cvtd
|
||||
/tests/fp80_cvtf
|
||||
/config.h
|
||||
/config.h.in
|
||||
/doxygen-doc
|
||||
/Doxyfile
|
||||
/Makefile.in
|
||||
/Makefile
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
package.m5
|
||||
stamp-h1
|
||||
.deps
|
||||
.libs
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*~
|
1
ext/fputils/AUTHORS
Normal file
1
ext/fputils/AUTHORS
Normal file
|
@ -0,0 +1 @@
|
|||
Andreas Sandberg <andreas@sandberg.pp.se>
|
22
ext/fputils/COPYING
Normal file
22
ext/fputils/COPYING
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2013, Andreas Sandberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
1792
ext/fputils/Doxyfile.in
Normal file
1792
ext/fputils/Doxyfile.in
Normal file
File diff suppressed because it is too large
Load diff
370
ext/fputils/INSTALL
Normal file
370
ext/fputils/INSTALL
Normal file
|
@ -0,0 +1,370 @@
|
|||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. This file is offered as-is,
|
||||
without warranty of any kind.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package. Some packages provide this
|
||||
`INSTALL' file but do not implement all of the features documented
|
||||
below. The lack of an optional feature in a given package is not
|
||||
necessarily a bug. More recommendations for GNU packages can be found
|
||||
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package, generally using the just-built uninstalled binaries.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation. When installing into a prefix owned by root, it is
|
||||
recommended that the package be configured and built as a regular
|
||||
user, and only the `make install' phase executed with root
|
||||
privileges.
|
||||
|
||||
5. Optionally, type `make installcheck' to repeat any self-tests, but
|
||||
this time using the binaries in their final installed location.
|
||||
This target does not install anything. Running this target as a
|
||||
regular user, particularly if the prior `make install' required
|
||||
root privileges, verifies that the installation completed
|
||||
correctly.
|
||||
|
||||
6. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
7. Often, you can also type `make uninstall' to remove the installed
|
||||
files again. In practice, not all packages have tested that
|
||||
uninstallation works correctly, even though it is required by the
|
||||
GNU Coding Standards.
|
||||
|
||||
8. Some packages, particularly those that use Automake, provide `make
|
||||
distcheck', which can by used by developers to test that all other
|
||||
targets like `make install' and `make uninstall' work correctly.
|
||||
This target is generally not run by end users.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'. This
|
||||
is known as a "VPATH" build.
|
||||
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple `-arch' options to the
|
||||
compiler but only a single `-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CPP="gcc -E" CXXCPP="g++ -E"
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the `lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX', where PREFIX must be an
|
||||
absolute file name.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them. In general, the
|
||||
default for these options is expressed in terms of `${prefix}', so that
|
||||
specifying just `--prefix' will affect all of the other directory
|
||||
specifications that were not explicitly provided.
|
||||
|
||||
The most portable way to affect installation locations is to pass the
|
||||
correct locations to `configure'; however, many packages provide one or
|
||||
both of the following shortcuts of passing variable assignments to the
|
||||
`make install' command line to change installation locations without
|
||||
having to reconfigure or recompile.
|
||||
|
||||
The first method involves providing an override variable for each
|
||||
affected directory. For example, `make install
|
||||
prefix=/alternate/directory' will choose an alternate location for all
|
||||
directory configuration variables that were expressed in terms of
|
||||
`${prefix}'. Any directories that were specified during `configure',
|
||||
but not in terms of `${prefix}', must each be overridden at install
|
||||
time for the entire installation to be relocated. The approach of
|
||||
makefile variable overrides for each directory variable is required by
|
||||
the GNU Coding Standards, and ideally causes no recompilation.
|
||||
However, some platforms have known limitations with the semantics of
|
||||
shared libraries that end up requiring recompilation when using this
|
||||
method, particularly noticeable in packages that use GNU Libtool.
|
||||
|
||||
The second method involves providing the `DESTDIR' variable. For
|
||||
example, `make install DESTDIR=/alternate/directory' will prepend
|
||||
`/alternate/directory' before all installation names. The approach of
|
||||
`DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||
does not work on platforms that have drive letters. On the other hand,
|
||||
it does better at avoiding recompilation issues, and works well even
|
||||
when some directory options were not specified in terms of `${prefix}'
|
||||
at `configure' time.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Some packages offer the ability to configure how verbose the
|
||||
execution of `make' will be. For these packages, running `./configure
|
||||
--enable-silent-rules' sets the default to minimal output, which can be
|
||||
overridden with `make V=1'; while running `./configure
|
||||
--disable-silent-rules' sets the default to verbose, which can be
|
||||
overridden with `make V=0'.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||
CC is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
HP-UX `make' updates targets which have the same time stamps as
|
||||
their prerequisites, which makes it generally unusable when shipped
|
||||
generated files such as `configure' are involved. Use GNU `make'
|
||||
instead.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||
to try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
|
||||
directory contains several dysfunctional programs; working variants of
|
||||
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
|
||||
in your `PATH', put it _after_ `/usr/bin'.
|
||||
|
||||
On Haiku, software installed for all users goes in `/boot/common',
|
||||
not `/usr/local'. It is recommended to use the following options:
|
||||
|
||||
./configure --prefix=/boot/common
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS
|
||||
KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of all of the options to `configure', and exit.
|
||||
|
||||
`--help=short'
|
||||
`--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
`configure', and exit. The `short' variant lists options used
|
||||
only in the top level, while the `recursive' variant lists options
|
||||
also present in any nested packages.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--prefix=DIR'
|
||||
Use DIR as the installation prefix. *note Installation Names::
|
||||
for more details, including other options available for fine-tuning
|
||||
the installation locations.
|
||||
|
||||
`--no-create'
|
||||
`-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
19
ext/fputils/Makefile.am
Normal file
19
ext/fputils/Makefile.am
Normal file
|
@ -0,0 +1,19 @@
|
|||
ACLOCAL_AMFLAGS=-I m4
|
||||
|
||||
SUBDIRS=. tests
|
||||
|
||||
MOSTLYCLEANFILES=
|
||||
|
||||
lib_LTLIBRARIES = libfputils.la
|
||||
|
||||
include_HEADERS = include/fputils/fp80.h
|
||||
|
||||
libfputils_la_SOURCES = \
|
||||
include/fputils/fp80.h \
|
||||
fpbits.h \
|
||||
fp80.c
|
||||
|
||||
|
||||
include $(top_srcdir)/doxygen.am
|
||||
|
||||
MOSTLYCLEANFILES += $(DX_CLEANFILES)
|
40
ext/fputils/SConscript
Normal file
40
ext/fputils/SConscript
Normal file
|
@ -0,0 +1,40 @@
|
|||
# -*- mode:python -*-
|
||||
|
||||
# Copyright (c) 2013 Andreas Sandberg
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met: redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer;
|
||||
# redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution;
|
||||
# neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Andreas Sandberg
|
||||
|
||||
Import('main')
|
||||
|
||||
main.Library('fputils', [
|
||||
main.SharedObject('fp80.c'),
|
||||
])
|
||||
|
||||
main.Prepend(CPPPATH=Dir('./include'))
|
||||
main.Append(LIBS=['fputils'])
|
||||
main.Prepend(LIBPATH=[Dir('.')])
|
||||
|
32
ext/fputils/configure.in
Normal file
32
ext/fputils/configure.in
Normal file
|
@ -0,0 +1,32 @@
|
|||
AC_INIT(libfputils, 1.0, andreas@sandberg.pp.se)
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
|
||||
|
||||
DX_PDF_FEATURE(OFF)
|
||||
DX_PS_FEATURE(OFF)
|
||||
DX_MAN_FEATURE(OFF)
|
||||
DX_INIT_DOXYGEN([libfputils])
|
||||
|
||||
AC_REQUIRE_AUX_FILE([tap-driver.sh])
|
||||
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_AWK
|
||||
|
||||
AM_CFLAGS="-Wall -Werror"
|
||||
AM_CPPFLAGS="-I\$(abs_top_srcdir)/include"
|
||||
|
||||
AC_SUBST(AM_CFLAGS)
|
||||
AC_SUBST(AM_CPPFLAGS)
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
AC_CONFIG_FILES([ \
|
||||
Doxyfile \
|
||||
Makefile \
|
||||
tests/Makefile \
|
||||
])
|
||||
AC_OUTPUT
|
105
ext/fputils/doxygen.am
Normal file
105
ext/fputils/doxygen.am
Normal file
|
@ -0,0 +1,105 @@
|
|||
## --------------------------------- ##
|
||||
## Format-independent Doxygen rules. ##
|
||||
## --------------------------------- ##
|
||||
if DX_COND_doc
|
||||
## ------------------------------- ##
|
||||
## Rules specific for HTML output. ##
|
||||
## ------------------------------- ##
|
||||
if DX_COND_html
|
||||
DX_CLEAN_HTML = @DX_DOCDIR@/html
|
||||
endif DX_COND_html
|
||||
## ------------------------------ ##
|
||||
## Rules specific for CHM output. ##
|
||||
## ------------------------------ ##
|
||||
if DX_COND_chm
|
||||
DX_CLEAN_CHM = @DX_DOCDIR@/chm
|
||||
if DX_COND_chi
|
||||
DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
|
||||
endif DX_COND_chi
|
||||
endif DX_COND_chm
|
||||
## ------------------------------ ##
|
||||
## Rules specific for MAN output. ##
|
||||
## ------------------------------ ##
|
||||
if DX_COND_man
|
||||
DX_CLEAN_MAN = @DX_DOCDIR@/man
|
||||
endif DX_COND_man
|
||||
## ------------------------------ ##
|
||||
## Rules specific for RTF output. ##
|
||||
## ------------------------------ ##
|
||||
if DX_COND_rtf
|
||||
DX_CLEAN_RTF = @DX_DOCDIR@/rtf
|
||||
endif DX_COND_rtf
|
||||
## ------------------------------ ##
|
||||
## Rules specific for XML output. ##
|
||||
## ------------------------------ ##
|
||||
if DX_COND_xml
|
||||
DX_CLEAN_XML = @DX_DOCDIR@/xml
|
||||
endif DX_COND_xml
|
||||
## ----------------------------- ##
|
||||
## Rules specific for PS output. ##
|
||||
## ----------------------------- ##
|
||||
if DX_COND_ps
|
||||
DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
|
||||
DX_PS_GOAL = doxygen-ps
|
||||
doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
|
||||
@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
|
||||
cd @DX_DOCDIR@/latex; \
|
||||
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
|
||||
$(DX_LATEX) refman.tex; \
|
||||
$(MAKEINDEX_PATH) refman.idx; \
|
||||
$(DX_LATEX) refman.tex; \
|
||||
countdown=5; \
|
||||
while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
|
||||
refman.log > /dev/null 2>&1 && test $$countdown -gt 0; do \
|
||||
$(DX_LATEX) refman.tex; \
|
||||
countdown=`expr $$countdown - 1`; \
|
||||
done; \
|
||||
$(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
|
||||
endif DX_COND_ps
|
||||
## ------------------------------ ##
|
||||
## Rules specific for PDF output. ##
|
||||
## ------------------------------ ##
|
||||
if DX_COND_pdf
|
||||
DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
|
||||
DX_PDF_GOAL = doxygen-pdf
|
||||
doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
|
||||
@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
|
||||
cd @DX_DOCDIR@/latex; \
|
||||
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
|
||||
$(DX_PDFLATEX) refman.tex; \
|
||||
$(DX_MAKEINDEX) refman.idx; \
|
||||
$(DX_PDFLATEX) refman.tex; \
|
||||
countdown=5; \
|
||||
while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
|
||||
refman.log > /dev/null 2>&1 && test $$countdown -gt 0; do \
|
||||
$(DX_PDFLATEX) refman.tex; \
|
||||
countdown=`expr $$countdown - 1`; \
|
||||
done; \
|
||||
mv refman.pdf ../@PACKAGE@.pdf
|
||||
endif DX_COND_pdf
|
||||
## ------------------------------------------------- ##
|
||||
## Rules specific for LaTeX (shared for PS and PDF). ##
|
||||
## ------------------------------------------------- ##
|
||||
if DX_COND_latex
|
||||
DX_CLEAN_LATEX = @DX_DOCDIR@/latex
|
||||
endif DX_COND_latex
|
||||
.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||
.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||
doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
|
||||
doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||
@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
|
||||
rm -rf @DX_DOCDIR@
|
||||
$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
|
||||
DX_CLEANFILES = \
|
||||
@DX_DOCDIR@/@PACKAGE@.tag \
|
||||
-r \
|
||||
$(DX_CLEAN_HTML) \
|
||||
$(DX_CLEAN_CHM) \
|
||||
$(DX_CLEAN_CHI) \
|
||||
$(DX_CLEAN_MAN) \
|
||||
$(DX_CLEAN_RTF) \
|
||||
$(DX_CLEAN_XML) \
|
||||
$(DX_CLEAN_PS) \
|
||||
$(DX_CLEAN_PDF) \
|
||||
$(DX_CLEAN_LATEX)
|
||||
endif DX_COND_doc
|
247
ext/fputils/fp80.c
Normal file
247
ext/fputils/fp80.c
Normal file
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Andreas Sandberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <fputils/fp80.h>
|
||||
#include "fpbits.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef union {
|
||||
union {
|
||||
uint64_t bits;
|
||||
double value;
|
||||
};
|
||||
} fp64_t;
|
||||
|
||||
|
||||
const fp80_t fp80_pinf = BUILD_FP80(0, 0, FP80_EXP_SPECIAL);
|
||||
const fp80_t fp80_ninf = BUILD_FP80(1, 0, FP80_EXP_SPECIAL);
|
||||
const fp80_t fp80_qnan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
|
||||
const fp80_t fp80_qnani = BUILD_FP80(1, FP80_FRAC_QNANI, FP80_EXP_SPECIAL);
|
||||
const fp80_t fp80_snan = BUILD_FP80(0, FP80_FRAC_SNAN, FP80_EXP_SPECIAL);
|
||||
const fp80_t fp80_nan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
|
||||
|
||||
static const fp64_t fp64_pinf = BUILD_FP64(0, 0, FP64_EXP_SPECIAL);
|
||||
static const fp64_t fp64_ninf = BUILD_FP64(1, 0, FP64_EXP_SPECIAL);
|
||||
static const fp64_t fp64_qnan = BUILD_FP64(0, FP64_FRAC_QNAN,
|
||||
FP64_EXP_SPECIAL);
|
||||
static const fp64_t fp64_nqnan = BUILD_FP64(1, FP64_FRAC_QNAN,
|
||||
FP64_EXP_SPECIAL);
|
||||
static const fp64_t fp64_qnani = BUILD_FP64(1, FP64_FRAC_QNANI,
|
||||
FP64_EXP_SPECIAL);
|
||||
static const fp64_t fp64_snan = BUILD_FP64(0, FP64_FRAC_SNAN,
|
||||
FP64_EXP_SPECIAL);
|
||||
static const fp64_t fp64_nsnan = BUILD_FP64(1, FP64_FRAC_SNAN,
|
||||
FP64_EXP_SPECIAL);
|
||||
|
||||
static double
|
||||
build_fp64(int sign, uint64_t frac, int exp)
|
||||
{
|
||||
const fp64_t f = BUILD_FP64(sign, frac, exp);
|
||||
|
||||
return f.value;
|
||||
}
|
||||
|
||||
int
|
||||
fp80_sgn(fp80_t fp80)
|
||||
{
|
||||
return (fp80.u.repr.se & FP80_SIGN_BIT) ? -1 : 1;
|
||||
}
|
||||
|
||||
int
|
||||
fp80_isspecial(fp80_t fp80)
|
||||
{
|
||||
const int exp = FP80_EXP(fp80);
|
||||
|
||||
return exp == FP80_EXP_SPECIAL;
|
||||
}
|
||||
|
||||
int
|
||||
fp80_isinf(fp80_t fp80)
|
||||
{
|
||||
const uint64_t frac = FP80_FRAC(fp80);
|
||||
|
||||
return fp80_isspecial(fp80) && frac == 0 ? fp80_sgn(fp80) : 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fp80_isqnan(fp80_t fp80)
|
||||
{
|
||||
const uint64_t frac = FP80_FRAC(fp80);
|
||||
|
||||
return fp80_isspecial(fp80) && (frac & FP80_QNAN_BIT);
|
||||
}
|
||||
|
||||
int
|
||||
fp80_isqnani(fp80_t fp80)
|
||||
{
|
||||
const uint64_t frac_low = fp80.u.repr.fi & (FP80_FRAC_MASK >> 1);
|
||||
|
||||
return fp80_isqnan(fp80) && (fp80.u.repr.se & FP80_SIGN_BIT) && !frac_low;
|
||||
}
|
||||
|
||||
int
|
||||
fp80_issnan(fp80_t fp80)
|
||||
{
|
||||
const uint64_t frac = FP80_FRAC(fp80);
|
||||
|
||||
return fp80_isspecial(fp80) && !(frac & FP80_QNAN_BIT) && frac;
|
||||
}
|
||||
|
||||
int
|
||||
fp80_isfinite(fp80_t fp80)
|
||||
{
|
||||
return !fp80_isnan(fp80) && !fp80_isinf(fp80);
|
||||
}
|
||||
|
||||
int
|
||||
fp80_isnan(fp80_t fp80)
|
||||
{
|
||||
return fp80_issnan(fp80) || fp80_isqnan(fp80) ? fp80_sgn(fp80) : 0;
|
||||
}
|
||||
|
||||
int
|
||||
fp80_iszero(fp80_t fp80)
|
||||
{
|
||||
return fp80.u.repr.fi == 0 && FP80_EXP(fp80) == 0 ? fp80_sgn(fp80) : 0;
|
||||
}
|
||||
|
||||
int
|
||||
fp80_isnormal(fp80_t fp80)
|
||||
{
|
||||
return FP80_EXP(fp80) != 0 && !fp80_isspecial(fp80) ?
|
||||
fp80_sgn(fp80) : 0;
|
||||
}
|
||||
|
||||
int
|
||||
fp80_issubnormal(fp80_t fp80)
|
||||
{
|
||||
return FP80_FRAC(fp80) && FP80_EXP(fp80) == 0 ? fp80_sgn(fp80) : 0;
|
||||
}
|
||||
|
||||
int
|
||||
fp80_classify(fp80_t fp80)
|
||||
{
|
||||
if (fp80_issubnormal(fp80)) {
|
||||
return FP_SUBNORMAL;
|
||||
} else if (fp80_iszero(fp80)) {
|
||||
return FP_ZERO;
|
||||
} else if (fp80_isinf(fp80)) {
|
||||
return FP_INFINITE;
|
||||
} else if (fp80_isnan(fp80)) {
|
||||
return FP_NAN;
|
||||
} else {
|
||||
assert(fp80_isfinite(fp80));
|
||||
return FP_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
fp80_cvtd(fp80_t fp80)
|
||||
{
|
||||
const int sign = fp80.u.repr.se & FP80_SIGN_BIT;
|
||||
|
||||
if (!fp80_isspecial(fp80)) {
|
||||
const uint64_t frac = fp80.u.repr.fi;
|
||||
const int unb_exp = FP80_EXP(fp80) - FP80_EXP_BIAS;
|
||||
const int fp64_exp = unb_exp + FP64_EXP_BIAS;
|
||||
const uint64_t fp64_frac = frac >> (FP80_FRAC_BITS - FP64_FRAC_BITS);
|
||||
|
||||
if (fp64_exp > 0 && fp64_exp < FP64_EXP_SPECIAL) {
|
||||
/* These numbers fall in the range of what we can express
|
||||
* as normals */
|
||||
return build_fp64(sign, fp64_frac, fp64_exp);
|
||||
} else if (fp64_exp <= 0) {
|
||||
uint64_t fp64_denormal_frac = fp64_frac >> (-fp64_exp);
|
||||
/* Generate a denormal or zero */
|
||||
return build_fp64(sign, fp64_denormal_frac, 0);
|
||||
} else {
|
||||
/* Infinity */
|
||||
return build_fp64(sign, 0, FP64_EXP_SPECIAL);
|
||||
}
|
||||
} else {
|
||||
if (fp80_isinf(fp80)) {
|
||||
return build_fp64(sign, 0, FP64_EXP_SPECIAL);
|
||||
} else if (fp80_issnan(fp80)) {
|
||||
return fp80_sgn(fp80) > 0 ? fp64_snan.value : fp64_nsnan.value;
|
||||
} else if (fp80_isqnani(fp80)) {
|
||||
return fp64_qnani.value;
|
||||
} else {
|
||||
assert(fp80_isqnan(fp80));
|
||||
return fp80_sgn(fp80) > 0 ? fp64_qnan.value : fp64_nqnan.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fp80_t
|
||||
fp80_cvfd(double value)
|
||||
{
|
||||
const fp64_t fp64 = { .value = value };
|
||||
const uint64_t frac = FP64_FRAC(fp64);
|
||||
const unsigned exp = FP64_EXP(fp64);
|
||||
const int unb_exp = exp - FP64_EXP_BIAS;
|
||||
const uint64_t fp80_frac = frac << (FP80_FRAC_BITS - FP64_FRAC_BITS);
|
||||
|
||||
if (exp != 0) {
|
||||
// Normal, inf, nan
|
||||
const unsigned fp80_exp = exp == FP64_EXP_SPECIAL ?
|
||||
FP80_EXP_SPECIAL : (unb_exp + FP80_EXP_BIAS);
|
||||
const fp80_t fp80 = BUILD_FP80(fp64.bits & FP64_SIGN_BIT,
|
||||
fp80_frac, fp80_exp);
|
||||
return fp80;
|
||||
} else if (exp == 0 && frac == 0) {
|
||||
// Zero
|
||||
const fp80_t fp80 = BUILD_FP80(fp64.bits & FP64_SIGN_BIT, 0, 0);
|
||||
return fp80;
|
||||
} else {
|
||||
// Denormal
|
||||
uint64_t fp80_fi = fp80_frac;
|
||||
int shift_amt = 0;
|
||||
while (!(fp80_fi & FP80_INT_BIT)) {
|
||||
fp80_fi <<= 1;
|
||||
++shift_amt;
|
||||
}
|
||||
const unsigned fp80_exp = (unb_exp - shift_amt) + FP80_EXP_BIAS;
|
||||
const fp80_t fp80 = BUILD_FP80(fp64.bits & FP64_SIGN_BIT,
|
||||
fp80_fi, fp80_exp);
|
||||
return fp80;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fp80_debug_dump(FILE *fout, fp80_t fp80)
|
||||
{
|
||||
fprintf(fout, "sgn: %i, int: %i, frac: 0x%llx, exp: 0x%x (%i)\n",
|
||||
fp80_sgn(fp80), !!(fp80.u.repr.fi & FP80_INT_BIT), FP80_FRAC(fp80),
|
||||
FP80_EXP(fp80), FP80_EXP(fp80) - FP80_EXP_BIAS);
|
||||
}
|
95
ext/fputils/fpbits.h
Normal file
95
ext/fputils/fpbits.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Andreas Sandberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FPBITS_H
|
||||
#define _FPBITS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define FP80_FRAC_BITS 63
|
||||
#define FP80_INT_BIT 0x8000000000000000ULL
|
||||
#define FP80_QNAN_BIT 0x4000000000000000ULL
|
||||
#define FP80_FRAC_MASK 0x7fffffffffffffffULL
|
||||
#define FP80_EXP_MASK 0x7fff
|
||||
#define FP80_SIGN_BIT 0x8000
|
||||
#define FP80_EXP_BIAS 0x3fff
|
||||
|
||||
#define FP80_EXP_SPECIAL 0x7fff
|
||||
#define FP80_FRAC_SNAN 0x3fffffffffffffffULL
|
||||
#define FP80_FRAC_QNAN 0x7fffffffffffffffULL
|
||||
#define FP80_FRAC_QNANI 0x4000000000000000ULL
|
||||
|
||||
|
||||
#define FP64_EXP_SHIFT 52
|
||||
#define FP64_FRAC_BITS 52
|
||||
#define FP64_SIGN_BIT 0x8000000000000000ULL
|
||||
#define FP64_EXP_MASK 0x7ff0000000000000ULL
|
||||
#define FP64_FRAC_MASK 0x000fffffffffffffULL
|
||||
#define FP64_EXP_BIAS 0x3ff
|
||||
|
||||
#define FP64_EXP_SPECIAL 0x7ff
|
||||
#define FP64_FRAC_SNAN 0x0007ffffffffffffULL
|
||||
#define FP64_FRAC_QNAN 0x000fffffffffffffULL
|
||||
#define FP64_FRAC_QNANI 0x0008000000000000ULL
|
||||
|
||||
#define BUILD_IFP64(sign, frac, exp) \
|
||||
((sign) ? FP64_SIGN_BIT : 0) | \
|
||||
(((uint64_t)(exp) << FP64_EXP_SHIFT) & FP64_EXP_MASK) | \
|
||||
((frac) & FP64_FRAC_MASK)
|
||||
|
||||
#define BUILD_FP64(sign, frac, exp) \
|
||||
{ .bits = BUILD_IFP64(sign, frac, exp) }
|
||||
|
||||
#define BUILD_FP80_SE(sign, exp) \
|
||||
((sign) ? FP80_SIGN_BIT : 0) | \
|
||||
((exp) & FP80_EXP_MASK)
|
||||
|
||||
#define BUILD_FP80_FI(frac, exp) \
|
||||
((exp) ? FP80_INT_BIT : 0) | \
|
||||
((frac) & FP80_FRAC_MASK)
|
||||
|
||||
#define BUILD_FP80(sign, frac, exp) \
|
||||
{ \
|
||||
.u.repr.se = BUILD_FP80_SE(sign, exp), \
|
||||
.u.repr.fi = BUILD_FP80_FI(frac, exp) \
|
||||
}
|
||||
|
||||
#define FP80_FRAC(fp80) \
|
||||
(fp80.u.repr.fi & FP80_FRAC_MASK)
|
||||
|
||||
#define FP80_EXP(fp80) \
|
||||
(fp80.u.repr.se & FP80_EXP_MASK)
|
||||
|
||||
#define FP64_FRAC(fp64) \
|
||||
(fp64.bits & FP64_FRAC_MASK)
|
||||
|
||||
#define FP64_EXP(fp80) \
|
||||
((fp64.bits & FP64_EXP_MASK) >> FP64_EXP_SHIFT)
|
||||
|
||||
#endif
|
253
ext/fputils/include/fputils/fp80.h
Normal file
253
ext/fputils/include/fputils/fp80.h
Normal file
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Andreas Sandberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _FP80_H
|
||||
#define _FP80_H 1
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup fp80 80-bit Floats
|
||||
* Functions handling 80-bit floats.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Internal representation of an 80-bit float. */
|
||||
typedef struct {
|
||||
union {
|
||||
char bits[10];
|
||||
struct {
|
||||
uint64_t fi;
|
||||
uint16_t se;
|
||||
} repr;
|
||||
} u;
|
||||
} fp80_t;
|
||||
|
||||
/** Constant representing +inf */
|
||||
extern const fp80_t fp80_pinf;
|
||||
/** Constant representing -inf */
|
||||
extern const fp80_t fp80_ninf;
|
||||
/** Constant representing a quiet NaN */
|
||||
extern const fp80_t fp80_qnan;
|
||||
/** Constant representing a quiet indefinite NaN */
|
||||
extern const fp80_t fp80_qnani;
|
||||
/** Constant representing a signaling NaN */
|
||||
extern const fp80_t fp80_snan;
|
||||
/** Alias for fp80_qnan */
|
||||
extern const fp80_t fp80_nan;
|
||||
|
||||
/**
|
||||
* Is the value a special floating point value?
|
||||
*
|
||||
* Determine if a floating point value is one of the special values
|
||||
* (i.e., one of the infinities or NaNs). In practice, this function
|
||||
* only checks if the exponent is set to the maximum value supported
|
||||
* by the binary representation, which is a reserved value used for
|
||||
* such special numbers.
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return 1 if the value is special, 0 otherwise.
|
||||
*/
|
||||
int fp80_isspecial(fp80_t fp80);
|
||||
/**
|
||||
* Is the value a quiet NaN?
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return 1 if true, 0 otherwise.
|
||||
*/
|
||||
int fp80_isqnan(fp80_t fp80);
|
||||
/**
|
||||
* Is the value an indefinite quiet NaN?
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return 1 if true, 0 otherwise.
|
||||
*/
|
||||
int fp80_isqnani(fp80_t fp80);
|
||||
/**
|
||||
* Is the value a signaling NaN?
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return 1 if true, 0 otherwise.
|
||||
*/
|
||||
int fp80_issnan(fp80_t fp80);
|
||||
|
||||
/**
|
||||
* Classify a floating point number.
|
||||
*
|
||||
* This function implements the same classification as the standard
|
||||
* fpclassify() function. It returns one of the following floating
|
||||
* point classes:
|
||||
* <ul>
|
||||
* <li>FP_NAN - The value is NaN.
|
||||
* <li>FP_INFINITE - The value is either +inf or -inf.
|
||||
* <li>FP_ZERO - The value is either +0 or -0.
|
||||
* <li>FP_SUBNORMAL - The value is to small to be represented as a
|
||||
* normalized float. See fp80_issubnormal().
|
||||
* <li>FP_NORMAL - The value is neither of above.
|
||||
* </ul>
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return Floating point classification.
|
||||
*/
|
||||
int fp80_classify(fp80_t fp80);
|
||||
|
||||
/**
|
||||
* Is a value finite?
|
||||
*
|
||||
* Check if a value is a finite value. That is, not one of the
|
||||
* infinities or NaNs.
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return -1 if negative finite, +1 if positive finite, 0 otherwise.
|
||||
*/
|
||||
int fp80_isfinite(fp80_t fp80);
|
||||
/**
|
||||
* Is the value a non-zero normal?
|
||||
*
|
||||
* This function checks if a floating point value is a normal (having
|
||||
* an exponent larger or equal to 1) or not. See fp80_issubnormal()
|
||||
* for a description of what a denormal value is.
|
||||
*
|
||||
* @see fp80_issubnormal()
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return -1 if negative normal, +1 if positive normal, 0 otherwise.
|
||||
*/
|
||||
int fp80_isnormal(fp80_t fp80);
|
||||
/**
|
||||
* Is the value a NaN of any kind?
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return -1 if negative NaN, +1 if positive NaN, 0 otherwise.
|
||||
*/
|
||||
int fp80_isnan(fp80_t fp80);
|
||||
/**
|
||||
* Is the value one of the infinities?
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return -1 if -inf, +1 if +inf, 0 otherwise.
|
||||
*/
|
||||
int fp80_isinf(fp80_t fp80);
|
||||
/**
|
||||
* Determine value of the sign-bit of a floating point number.
|
||||
*
|
||||
* @note Floats can represent both positive and negative zeros.
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return -1 if negative, +1 if positive.
|
||||
*/
|
||||
int fp80_sgn(fp80_t fp80);
|
||||
/**
|
||||
* Is the value zero?
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return -1 if negative zero, +1 if positive zero, 0 otherwise.
|
||||
*/
|
||||
int fp80_iszero(fp80_t fp80);
|
||||
/**
|
||||
* Is the value a denormal?
|
||||
*
|
||||
* Numbers that are close to the minimum of what can be stored in a
|
||||
* floating point number start loosing precision because bits in the
|
||||
* fraction get used (implicitly) to store parts of the negative
|
||||
* exponent (i.e., the exponent is saturated and the fraction is less
|
||||
* than 1). Such numbers are known as denormals. This function checks
|
||||
* whether a float is a denormal or not.
|
||||
*
|
||||
* @param fp80 value to analyze.
|
||||
* @return -1 if negative denormal, +1 if positive denormal, 0 otherwise.
|
||||
*/
|
||||
int fp80_issubnormal(fp80_t fp80);
|
||||
|
||||
/**
|
||||
* Convert an 80-bit float to a 64-bit double.
|
||||
*
|
||||
* This function converts an 80-bit float into a standard 64-bit
|
||||
* double. This conversion is inherently lossy since a double can only
|
||||
* represent a subset of what an 80-bit float can represent. The
|
||||
* fraction of the source value will always be truncated to fit the
|
||||
* lower precision. If a value falls outside of the range that can be
|
||||
* accurately represented by double by truncating the fraction, one of
|
||||
* the following happens:
|
||||
* <ul>
|
||||
* <li>A denormal will be generated if that can approximate the
|
||||
* value.
|
||||
* <li>[-]0 will be generated if the magnitude of the value is too
|
||||
* small to be represented at all.
|
||||
* <li>+-Inf will be generated if the magnitude of the value is too
|
||||
* large to be represented.
|
||||
* </ul>
|
||||
*
|
||||
* NaN values will be preserved across the conversion.
|
||||
*
|
||||
* @param fp80 Source value to convert.
|
||||
* @return 64-bit version of the float.
|
||||
*/
|
||||
double fp80_cvtd(fp80_t fp80);
|
||||
|
||||
/**
|
||||
* Convert an 64-bit double to an 80-bit float.
|
||||
*
|
||||
* This function converts a standard 64-bit double into an 80-bit
|
||||
* float. This conversion is completely lossless since the 80-bit
|
||||
* float represents a superset of what a 64-bit double can
|
||||
* represent.
|
||||
*
|
||||
* @note Denormals will be converted to normalized values.
|
||||
*
|
||||
* @param fpd Source value to convert.
|
||||
* @return 64-bit version of the float.
|
||||
*/
|
||||
fp80_t fp80_cvfd(double fpd);
|
||||
|
||||
/**
|
||||
* Dump the components of an 80-bit float to a file.
|
||||
*
|
||||
* @warning This function is intended for debugging and the format of
|
||||
* the output is not guaranteed to be stable.
|
||||
*
|
||||
* @param fout Output stream (e.g., stdout)
|
||||
* @param fp80 value to dump.
|
||||
*/
|
||||
void fp80_debug_dump(FILE *fout, fp80_t fp80);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
532
ext/fputils/m4/ax_prog_doxygen.m4
Normal file
532
ext/fputils/m4/ax_prog_doxygen.m4
Normal file
|
@ -0,0 +1,532 @@
|
|||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# DX_INIT_DOXYGEN(PROJECT-NAME, DOXYFILE-PATH, [OUTPUT-DIR])
|
||||
# DX_DOXYGEN_FEATURE(ON|OFF)
|
||||
# DX_DOT_FEATURE(ON|OFF)
|
||||
# DX_HTML_FEATURE(ON|OFF)
|
||||
# DX_CHM_FEATURE(ON|OFF)
|
||||
# DX_CHI_FEATURE(ON|OFF)
|
||||
# DX_MAN_FEATURE(ON|OFF)
|
||||
# DX_RTF_FEATURE(ON|OFF)
|
||||
# DX_XML_FEATURE(ON|OFF)
|
||||
# DX_PDF_FEATURE(ON|OFF)
|
||||
# DX_PS_FEATURE(ON|OFF)
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# The DX_*_FEATURE macros control the default setting for the given
|
||||
# Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for
|
||||
# generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML
|
||||
# help (for MS users), 'CHI' for generating a seperate .chi file by the
|
||||
# .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate
|
||||
# output formats. The environment variable DOXYGEN_PAPER_SIZE may be
|
||||
# specified to override the default 'a4wide' paper size.
|
||||
#
|
||||
# By default, HTML, PDF and PS documentation is generated as this seems to
|
||||
# be the most popular and portable combination. MAN pages created by
|
||||
# Doxygen are usually problematic, though by picking an appropriate subset
|
||||
# and doing some massaging they might be better than nothing. CHM and RTF
|
||||
# are specific for MS (note that you can't generate both HTML and CHM at
|
||||
# the same time). The XML is rather useless unless you apply specialized
|
||||
# post-processing to it.
|
||||
#
|
||||
# The macros mainly control the default state of the feature. The use can
|
||||
# override the default by specifying --enable or --disable. The macros
|
||||
# ensure that contradictory flags are not given (e.g.,
|
||||
# --enable-doxygen-html and --enable-doxygen-chm,
|
||||
# --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each
|
||||
# feature will be automatically disabled (with a warning) if the required
|
||||
# programs are missing.
|
||||
#
|
||||
# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN
|
||||
# with the following parameters: a one-word name for the project for use
|
||||
# as a filename base etc., an optional configuration file name (the
|
||||
# default is 'Doxyfile', the same as Doxygen's default), and an optional
|
||||
# output directory name (the default is 'doxygen-doc').
|
||||
#
|
||||
# Automake Support
|
||||
#
|
||||
# The following is a template aminclude.am file for use with Automake.
|
||||
# Make targets and variables values are controlled by the various
|
||||
# DX_COND_* conditionals set by autoconf.
|
||||
#
|
||||
# The provided targets are:
|
||||
#
|
||||
# doxygen-doc: Generate all doxygen documentation.
|
||||
#
|
||||
# doxygen-run: Run doxygen, which will generate some of the
|
||||
# documentation (HTML, CHM, CHI, MAN, RTF, XML)
|
||||
# but will not do the post processing required
|
||||
# for the rest of it (PS, PDF, and some MAN).
|
||||
#
|
||||
# doxygen-man: Rename some doxygen generated man pages.
|
||||
#
|
||||
# doxygen-ps: Generate doxygen PostScript documentation.
|
||||
#
|
||||
# doxygen-pdf: Generate doxygen PDF documentation.
|
||||
#
|
||||
# Note that by default these are not integrated into the automake targets.
|
||||
# If doxygen is used to generate man pages, you can achieve this
|
||||
# integration by setting man3_MANS to the list of man pages generated and
|
||||
# then adding the dependency:
|
||||
#
|
||||
# $(man3_MANS): doxygen-doc
|
||||
#
|
||||
# This will cause make to run doxygen and generate all the documentation.
|
||||
#
|
||||
# The following variable is intended for use in Makefile.am:
|
||||
#
|
||||
# DX_CLEANFILES = everything to clean.
|
||||
#
|
||||
# Then add this variable to MOSTLYCLEANFILES.
|
||||
#
|
||||
# ----- begin aminclude.am -------------------------------------
|
||||
#
|
||||
# ## --------------------------------- ##
|
||||
# ## Format-independent Doxygen rules. ##
|
||||
# ## --------------------------------- ##
|
||||
#
|
||||
# if DX_COND_doc
|
||||
#
|
||||
# ## ------------------------------- ##
|
||||
# ## Rules specific for HTML output. ##
|
||||
# ## ------------------------------- ##
|
||||
#
|
||||
# if DX_COND_html
|
||||
#
|
||||
# DX_CLEAN_HTML = @DX_DOCDIR@/html
|
||||
#
|
||||
# endif DX_COND_html
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for CHM output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_chm
|
||||
#
|
||||
# DX_CLEAN_CHM = @DX_DOCDIR@/chm
|
||||
#
|
||||
# if DX_COND_chi
|
||||
#
|
||||
# DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
|
||||
#
|
||||
# endif DX_COND_chi
|
||||
#
|
||||
# endif DX_COND_chm
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for MAN output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_man
|
||||
#
|
||||
# DX_CLEAN_MAN = @DX_DOCDIR@/man
|
||||
#
|
||||
# endif DX_COND_man
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for RTF output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_rtf
|
||||
#
|
||||
# DX_CLEAN_RTF = @DX_DOCDIR@/rtf
|
||||
#
|
||||
# endif DX_COND_rtf
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for XML output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_xml
|
||||
#
|
||||
# DX_CLEAN_XML = @DX_DOCDIR@/xml
|
||||
#
|
||||
# endif DX_COND_xml
|
||||
#
|
||||
# ## ----------------------------- ##
|
||||
# ## Rules specific for PS output. ##
|
||||
# ## ----------------------------- ##
|
||||
#
|
||||
# if DX_COND_ps
|
||||
#
|
||||
# DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
|
||||
#
|
||||
# DX_PS_GOAL = doxygen-ps
|
||||
#
|
||||
# doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
|
||||
#
|
||||
# @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
|
||||
# cd @DX_DOCDIR@/latex; \
|
||||
# rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
|
||||
# $(DX_LATEX) refman.tex; \
|
||||
# $(MAKEINDEX_PATH) refman.idx; \
|
||||
# $(DX_LATEX) refman.tex; \
|
||||
# countdown=5; \
|
||||
# while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
|
||||
# refman.log > /dev/null 2>&1 \
|
||||
# && test $$countdown -gt 0; do \
|
||||
# $(DX_LATEX) refman.tex; \
|
||||
# countdown=`expr $$countdown - 1`; \
|
||||
# done; \
|
||||
# $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
|
||||
#
|
||||
# endif DX_COND_ps
|
||||
#
|
||||
# ## ------------------------------ ##
|
||||
# ## Rules specific for PDF output. ##
|
||||
# ## ------------------------------ ##
|
||||
#
|
||||
# if DX_COND_pdf
|
||||
#
|
||||
# DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
|
||||
#
|
||||
# DX_PDF_GOAL = doxygen-pdf
|
||||
#
|
||||
# doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
|
||||
#
|
||||
# @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
|
||||
# cd @DX_DOCDIR@/latex; \
|
||||
# rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
|
||||
# $(DX_PDFLATEX) refman.tex; \
|
||||
# $(DX_MAKEINDEX) refman.idx; \
|
||||
# $(DX_PDFLATEX) refman.tex; \
|
||||
# countdown=5; \
|
||||
# while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
|
||||
# refman.log > /dev/null 2>&1 \
|
||||
# && test $$countdown -gt 0; do \
|
||||
# $(DX_PDFLATEX) refman.tex; \
|
||||
# countdown=`expr $$countdown - 1`; \
|
||||
# done; \
|
||||
# mv refman.pdf ../@PACKAGE@.pdf
|
||||
#
|
||||
# endif DX_COND_pdf
|
||||
#
|
||||
# ## ------------------------------------------------- ##
|
||||
# ## Rules specific for LaTeX (shared for PS and PDF). ##
|
||||
# ## ------------------------------------------------- ##
|
||||
#
|
||||
# if DX_COND_latex
|
||||
#
|
||||
# DX_CLEAN_LATEX = @DX_DOCDIR@/latex
|
||||
#
|
||||
# endif DX_COND_latex
|
||||
#
|
||||
# .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||
#
|
||||
# .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||
#
|
||||
# doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
|
||||
#
|
||||
# doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||
#
|
||||
# @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
|
||||
# rm -rf @DX_DOCDIR@
|
||||
# $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
|
||||
#
|
||||
# DX_CLEANFILES = \
|
||||
# @DX_DOCDIR@/@PACKAGE@.tag \
|
||||
# -r \
|
||||
# $(DX_CLEAN_HTML) \
|
||||
# $(DX_CLEAN_CHM) \
|
||||
# $(DX_CLEAN_CHI) \
|
||||
# $(DX_CLEAN_MAN) \
|
||||
# $(DX_CLEAN_RTF) \
|
||||
# $(DX_CLEAN_XML) \
|
||||
# $(DX_CLEAN_PS) \
|
||||
# $(DX_CLEAN_PDF) \
|
||||
# $(DX_CLEAN_LATEX)
|
||||
#
|
||||
# endif DX_COND_doc
|
||||
#
|
||||
# ----- end aminclude.am ---------------------------------------
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2009 Oren Ben-Kiki <oren@ben-kiki.org>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 12
|
||||
|
||||
## ----------##
|
||||
## Defaults. ##
|
||||
## ----------##
|
||||
|
||||
DX_ENV=""
|
||||
AC_DEFUN([DX_FEATURE_doc], ON)
|
||||
AC_DEFUN([DX_FEATURE_dot], OFF)
|
||||
AC_DEFUN([DX_FEATURE_man], OFF)
|
||||
AC_DEFUN([DX_FEATURE_html], ON)
|
||||
AC_DEFUN([DX_FEATURE_chm], OFF)
|
||||
AC_DEFUN([DX_FEATURE_chi], OFF)
|
||||
AC_DEFUN([DX_FEATURE_rtf], OFF)
|
||||
AC_DEFUN([DX_FEATURE_xml], OFF)
|
||||
AC_DEFUN([DX_FEATURE_pdf], ON)
|
||||
AC_DEFUN([DX_FEATURE_ps], ON)
|
||||
|
||||
## --------------- ##
|
||||
## Private macros. ##
|
||||
## --------------- ##
|
||||
|
||||
# DX_ENV_APPEND(VARIABLE, VALUE)
|
||||
# ------------------------------
|
||||
# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
|
||||
AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
|
||||
|
||||
# DX_DIRNAME_EXPR
|
||||
# ---------------
|
||||
# Expand into a shell expression prints the directory part of a path.
|
||||
AC_DEFUN([DX_DIRNAME_EXPR],
|
||||
[[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
|
||||
|
||||
# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
|
||||
# -------------------------------------
|
||||
# Expands according to the M4 (static) status of the feature.
|
||||
AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
|
||||
|
||||
# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
|
||||
# ----------------------------------
|
||||
# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
|
||||
AC_DEFUN([DX_REQUIRE_PROG], [
|
||||
AC_PATH_TOOL([$1], [$2])
|
||||
if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
|
||||
AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
|
||||
AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
|
||||
fi
|
||||
])
|
||||
|
||||
# DX_TEST_FEATURE(FEATURE)
|
||||
# ------------------------
|
||||
# Expand to a shell expression testing whether the feature is active.
|
||||
AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
|
||||
|
||||
# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
|
||||
# -------------------------------------------------
|
||||
# Verify that a required features has the right state before trying to turn on
|
||||
# the DX_CURRENT_FEATURE.
|
||||
AC_DEFUN([DX_CHECK_DEPEND], [
|
||||
test "$DX_FLAG_$1" = "$2" \
|
||||
|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
|
||||
requires, contradicts) doxygen-DX_CURRENT_FEATURE])
|
||||
])
|
||||
|
||||
# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
|
||||
# ----------------------------------------------------------
|
||||
# Turn off the DX_CURRENT_FEATURE if the required feature is off.
|
||||
AC_DEFUN([DX_CLEAR_DEPEND], [
|
||||
test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
|
||||
])
|
||||
|
||||
# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
|
||||
# CHECK_DEPEND, CLEAR_DEPEND,
|
||||
# REQUIRE, DO-IF-ON, DO-IF-OFF)
|
||||
# --------------------------------------------
|
||||
# Parse the command-line option controlling a feature. CHECK_DEPEND is called
|
||||
# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
|
||||
# otherwise CLEAR_DEPEND is called to turn off the default state if a required
|
||||
# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
|
||||
# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
|
||||
# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
|
||||
AC_DEFUN([DX_ARG_ABLE], [
|
||||
AC_DEFUN([DX_CURRENT_FEATURE], [$1])
|
||||
AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
|
||||
AC_ARG_ENABLE(doxygen-$1,
|
||||
[AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
|
||||
[--enable-doxygen-$1]),
|
||||
DX_IF_FEATURE([$1], [don't $2], [$2]))],
|
||||
[
|
||||
case "$enableval" in
|
||||
#(
|
||||
y|Y|yes|Yes|YES)
|
||||
AC_SUBST([DX_FLAG_$1], 1)
|
||||
$3
|
||||
;; #(
|
||||
n|N|no|No|NO)
|
||||
AC_SUBST([DX_FLAG_$1], 0)
|
||||
;; #(
|
||||
*)
|
||||
AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
|
||||
;;
|
||||
esac
|
||||
], [
|
||||
AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
|
||||
$4
|
||||
])
|
||||
if DX_TEST_FEATURE([$1]); then
|
||||
$5
|
||||
:
|
||||
fi
|
||||
AM_CONDITIONAL(DX_COND_$1, DX_TEST_FEATURE([$1]))
|
||||
if DX_TEST_FEATURE([$1]); then
|
||||
$6
|
||||
:
|
||||
else
|
||||
$7
|
||||
:
|
||||
fi
|
||||
])
|
||||
|
||||
## -------------- ##
|
||||
## Public macros. ##
|
||||
## -------------- ##
|
||||
|
||||
# DX_XXX_FEATURE(DEFAULT_STATE)
|
||||
# -----------------------------
|
||||
AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])])
|
||||
AC_DEFUN([DX_DOT_FEATURE], [AC_DEFUN([DX_FEATURE_dot], [$1])])
|
||||
AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])])
|
||||
AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])])
|
||||
AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])])
|
||||
AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])])
|
||||
AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])])
|
||||
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
|
||||
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
|
||||
AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])])
|
||||
AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])])
|
||||
|
||||
# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
|
||||
# ---------------------------------------------------------
|
||||
# PROJECT also serves as the base name for the documentation files.
|
||||
# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
|
||||
AC_DEFUN([DX_INIT_DOXYGEN], [
|
||||
|
||||
# Files:
|
||||
AC_SUBST([DX_PROJECT], [$1])
|
||||
AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
|
||||
AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
|
||||
|
||||
# Environment variables used inside doxygen.cfg:
|
||||
DX_ENV_APPEND(SRCDIR, $srcdir)
|
||||
DX_ENV_APPEND(PROJECT, $DX_PROJECT)
|
||||
DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
|
||||
DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
|
||||
|
||||
# Doxygen itself:
|
||||
DX_ARG_ABLE(doc, [generate any doxygen documentation],
|
||||
[],
|
||||
[],
|
||||
[DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
|
||||
DX_REQUIRE_PROG([DX_PERL], perl)],
|
||||
[DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
|
||||
|
||||
# Dot for graphics:
|
||||
DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[DX_REQUIRE_PROG([DX_DOT], dot)],
|
||||
[DX_ENV_APPEND(HAVE_DOT, YES)
|
||||
DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
|
||||
[DX_ENV_APPEND(HAVE_DOT, NO)])
|
||||
|
||||
# Man pages generation:
|
||||
DX_ARG_ABLE(man, [generate doxygen manual pages],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_MAN, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_MAN, NO)])
|
||||
|
||||
# RTF file generation:
|
||||
DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_RTF, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_RTF, NO)])
|
||||
|
||||
# XML file generation:
|
||||
DX_ARG_ABLE(xml, [generate doxygen XML documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_XML, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_XML, NO)])
|
||||
|
||||
# (Compressed) HTML help generation:
|
||||
DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[DX_REQUIRE_PROG([DX_HHC], hhc)],
|
||||
[DX_ENV_APPEND(HHC_PATH, $DX_HHC)
|
||||
DX_ENV_APPEND(GENERATE_HTML, YES)
|
||||
DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
|
||||
|
||||
# Seperate CHI file generation.
|
||||
DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
|
||||
[DX_CHECK_DEPEND(chm, 1)],
|
||||
[DX_CLEAR_DEPEND(chm, 1)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_CHI, YES)],
|
||||
[DX_ENV_APPEND(GENERATE_CHI, NO)])
|
||||
|
||||
# Plain HTML pages generation:
|
||||
DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
|
||||
[DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
|
||||
[],
|
||||
[DX_ENV_APPEND(GENERATE_HTML, YES)],
|
||||
[DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
|
||||
|
||||
# PostScript file generation:
|
||||
DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[DX_REQUIRE_PROG([DX_LATEX], latex)
|
||||
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
|
||||
DX_REQUIRE_PROG([DX_DVIPS], dvips)
|
||||
DX_REQUIRE_PROG([DX_EGREP], egrep)])
|
||||
|
||||
# PDF file generation:
|
||||
DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
|
||||
[DX_CHECK_DEPEND(doc, 1)],
|
||||
[DX_CLEAR_DEPEND(doc, 1)],
|
||||
[DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
|
||||
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
|
||||
DX_REQUIRE_PROG([DX_EGREP], egrep)])
|
||||
|
||||
# LaTeX generation for PS and/or PDF:
|
||||
AM_CONDITIONAL(DX_COND_latex, DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf))
|
||||
if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
|
||||
DX_ENV_APPEND(GENERATE_LATEX, YES)
|
||||
else
|
||||
DX_ENV_APPEND(GENERATE_LATEX, NO)
|
||||
fi
|
||||
|
||||
# Paper size for PS and/or PDF:
|
||||
AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
|
||||
[a4wide (default), a4, letter, legal or executive])
|
||||
case "$DOXYGEN_PAPER_SIZE" in
|
||||
#(
|
||||
"")
|
||||
AC_SUBST(DOXYGEN_PAPER_SIZE, "")
|
||||
;; #(
|
||||
a4wide|a4|letter|legal|executive)
|
||||
DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
|
||||
;; #(
|
||||
*)
|
||||
AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
|
||||
;;
|
||||
esac
|
||||
|
||||
#For debugging:
|
||||
#echo DX_FLAG_doc=$DX_FLAG_doc
|
||||
#echo DX_FLAG_dot=$DX_FLAG_dot
|
||||
#echo DX_FLAG_man=$DX_FLAG_man
|
||||
#echo DX_FLAG_html=$DX_FLAG_html
|
||||
#echo DX_FLAG_chm=$DX_FLAG_chm
|
||||
#echo DX_FLAG_chi=$DX_FLAG_chi
|
||||
#echo DX_FLAG_rtf=$DX_FLAG_rtf
|
||||
#echo DX_FLAG_xml=$DX_FLAG_xml
|
||||
#echo DX_FLAG_pdf=$DX_FLAG_pdf
|
||||
#echo DX_FLAG_ps=$DX_FLAG_ps
|
||||
#echo DX_ENV=$DX_ENV
|
||||
])
|
13
ext/fputils/tests/Makefile.am
Normal file
13
ext/fputils/tests/Makefile.am
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
|
||||
$(top_srcdir)/tap-driver.sh
|
||||
|
||||
LIBS=-lm $(top_builddir)/.libs/libfputils.la libtest.a
|
||||
|
||||
FP80_TESTS=fp80_cvtd fp80_cvfd fp80_cvtf
|
||||
TESTS=$(FP80_TESTS)
|
||||
|
||||
check_LIBRARIES=libtest.a
|
||||
check_PROGRAMS=$(FP80_TESTS)
|
||||
|
||||
libtest_a_SOURCES=test_helper.c test_helper.h
|
120
ext/fputils/tests/fp80_cvfd.c
Normal file
120
ext/fputils/tests/fp80_cvfd.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Andreas Sandberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <fputils/fp80.h>
|
||||
|
||||
#include "test_helper.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void
|
||||
test_cvfd_class(const char *name, double fin)
|
||||
{
|
||||
test_diag("converting '%e' -> fp80...", fin);
|
||||
fp80_t v = fp80_cvfd(fin);
|
||||
int class_ok;
|
||||
int fp64_class = fpclassify(fin);
|
||||
int class = fp64_class == FP_SUBNORMAL ? FP_NORMAL : fp64_class;
|
||||
int fp80_class = fp80_classify(v);
|
||||
|
||||
printf("# ");
|
||||
fp80_debug_dump(stdout, v);
|
||||
test_diag("isnan: %i, isinf: %i, iszero: %i, isnormal: %i, issubnormal: %i",
|
||||
fp80_isnan(v), fp80_isinf(v), fp80_iszero(v),
|
||||
fp80_isnormal(v), fp80_issubnormal(v));
|
||||
test_diag("class(fp64): %i, expected class: %i, class(fp80): %i",
|
||||
fp64_class, class, fp80_classify(v));
|
||||
switch (class) {
|
||||
case FP_NAN:
|
||||
class_ok = fp80_isnan(v) && !fp80_isinf(v) && !fp80_iszero(v) &&
|
||||
!fp80_isnormal(v) && !fp80_issubnormal(v);
|
||||
break;
|
||||
|
||||
case FP_INFINITE:
|
||||
class_ok = !fp80_isnan(v) && fp80_isinf(v) && !fp80_iszero(v) &&
|
||||
!fp80_isnormal(v) && !fp80_issubnormal(v);
|
||||
break;
|
||||
case FP_ZERO:
|
||||
class_ok = !fp80_isnan(v) && !fp80_isinf(v) && fp80_iszero(v) &&
|
||||
!fp80_isnormal(v) && !fp80_issubnormal(v);
|
||||
break;
|
||||
|
||||
case FP_SUBNORMAL:
|
||||
class_ok = !fp80_isnan(v) && !fp80_isinf(v) && !fp80_iszero(v) &&
|
||||
!fp80_isnormal(v) && fp80_issubnormal(v);
|
||||
break;
|
||||
|
||||
case FP_NORMAL:
|
||||
class_ok = !fp80_isnan(v) && !fp80_isinf(v) && !fp80_iszero(v) &&
|
||||
fp80_isnormal(v) && !fp80_issubnormal(v);
|
||||
break;
|
||||
|
||||
default:
|
||||
test_bail("unexpected FP class (%i)", class);
|
||||
}
|
||||
|
||||
if (!class_ok) {
|
||||
test_diag("inconsistent classification");
|
||||
test_fail(name);
|
||||
} else if (fp80_class != class) {
|
||||
test_diag("class mismatch");
|
||||
test_fail(name);
|
||||
} else {
|
||||
test_ok(name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_cvfd_class_exp(const char *name, double x, int exp)
|
||||
{
|
||||
double val = ldexp(x, exp);
|
||||
test_cvfd_class(name, val);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
test_init(9);
|
||||
|
||||
test_cvfd_class("double->fp80 +inf", -INFINITY);
|
||||
test_cvfd_class("double->fp80 -inf", INFINITY);
|
||||
test_cvfd_class("double->fp80 +nan", NAN);
|
||||
test_cvfd_class("double->fp80 -nan", -NAN);
|
||||
test_cvfd_class("double->fp80 +0", 0);
|
||||
test_cvfd_class("double->fp80 PI", M_PI);
|
||||
|
||||
test_cvfd_class_exp("double->fp80 smallest normal", 1.0, -1022);
|
||||
test_cvfd_class_exp("double->fp80 denormal1", 0.5, -1022);
|
||||
test_cvfd_class_exp("double->fp80 denormal2", 0.25, -1022);
|
||||
|
||||
test_exit();
|
||||
}
|
75
ext/fputils/tests/fp80_cvtd.c
Normal file
75
ext/fputils/tests/fp80_cvtd.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Andreas Sandberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <fputils/fp80.h>
|
||||
|
||||
#include "test_helper.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void
|
||||
test_fp80_cvtd_class(const char *name, fp80_t fin, int class)
|
||||
{
|
||||
double d = fp80_cvtd(fin);
|
||||
if (fpclassify(d) != class) {
|
||||
test_diag("wrong class");
|
||||
test_fail(name);
|
||||
} else {
|
||||
test_ok(name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_fp80_cvtd_inf(const char *name, fp80_t fin, int inf_class)
|
||||
{
|
||||
double d = fp80_cvtd(fin);
|
||||
if (isinf(d) != inf_class) {
|
||||
test_diag("wrong infinity type");
|
||||
test_fail(name);
|
||||
} else {
|
||||
test_ok(name);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
test_init(6);
|
||||
|
||||
test_fp80_cvtd_inf("fp80->double +inf", fp80_pinf, 1);
|
||||
test_fp80_cvtd_inf("fp80->double -inf", fp80_ninf, -1);
|
||||
test_fp80_cvtd_class("fp80->double qnan", fp80_qnan, FP_NAN);
|
||||
test_fp80_cvtd_class("fp80->double qnani", fp80_qnani, FP_NAN);
|
||||
test_fp80_cvtd_class("fp80->double snan", fp80_snan, FP_NAN);
|
||||
test_fp80_cvtd_class("fp80->double nan", fp80_nan, FP_NAN);
|
||||
|
||||
test_exit();
|
||||
}
|
82
ext/fputils/tests/fp80_cvtf.c
Normal file
82
ext/fputils/tests/fp80_cvtf.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Andreas Sandberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <fputils/fp80.h>
|
||||
|
||||
#include "test_helper.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void
|
||||
test_cvtf(const char *name, double fin)
|
||||
{
|
||||
fp80_t v80 = fp80_cvfd(fin);
|
||||
double v64 = fp80_cvtd(v80);
|
||||
|
||||
test_diag("Conversion '%e' -> fp80 -> double: %e", fin, v64);
|
||||
|
||||
printf("# ");
|
||||
fp80_debug_dump(stdout, v80);
|
||||
if (v64 == fin ||
|
||||
(isnan(fin) && isnan(v64) && signbit(fin) == signbit(v64))) {
|
||||
test_ok(name);
|
||||
} else {
|
||||
test_diag("MISMATCH: %e != %e", fin, v64);
|
||||
test_fail(name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_cvtf_exp(const char *name, double x, int exp)
|
||||
{
|
||||
double val = ldexp(x, exp);
|
||||
test_cvtf(name, val);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
test_init(9);
|
||||
|
||||
test_cvtf("+inf", -INFINITY);
|
||||
test_cvtf("-inf", INFINITY);
|
||||
test_cvtf("+nan", NAN);
|
||||
test_cvtf("-nan", -NAN);
|
||||
test_cvtf("+0", 0);
|
||||
test_cvtf("PI", M_PI);
|
||||
|
||||
test_cvtf_exp("smallest normal", 1.0, -1022);
|
||||
test_cvtf_exp("denormal1", 0.5, -1022);
|
||||
test_cvtf_exp("denormal2", 0.25, -1022);
|
||||
|
||||
test_exit();
|
||||
}
|
157
ext/fputils/tests/test_helper.c
Normal file
157
ext/fputils/tests/test_helper.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Andreas Sandberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned test_current = 0;
|
||||
unsigned test_count = 0;
|
||||
unsigned test_fail_count = 0;
|
||||
|
||||
void
|
||||
test_init(unsigned no_tests)
|
||||
{
|
||||
assert(test_count == 0 && test_current == 0);
|
||||
|
||||
test_count = no_tests;
|
||||
test_current = 1;
|
||||
test_fail_count = 0;
|
||||
|
||||
printf("1..%u\n", no_tests);
|
||||
}
|
||||
|
||||
void
|
||||
test_exit()
|
||||
{
|
||||
if (test_fail_count)
|
||||
exit(EXIT_FAILURE);
|
||||
else
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
test_bail(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
printf("Bail out! ");
|
||||
vprintf(fmt, ap);
|
||||
printf("\n");
|
||||
|
||||
va_end(ap);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void
|
||||
test_diag(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
printf("# ");
|
||||
vprintf(fmt, ap);
|
||||
printf("\n");
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void
|
||||
test_vstatus(const char *status, const char *test,
|
||||
const char *directive,
|
||||
const char *fmt_why, va_list ap)
|
||||
{
|
||||
printf("%s %i", status, test_current);
|
||||
|
||||
if (test && test[0] != '\0')
|
||||
printf(" - %s", test);
|
||||
|
||||
if (directive && directive[0] != '\0') {
|
||||
printf(" # %s ", directive);
|
||||
if (fmt_why && fmt_why[0] != '\0')
|
||||
vprintf(fmt_why, ap);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
++test_current;
|
||||
}
|
||||
|
||||
static void __attribute__((format (printf, 4, 5)))
|
||||
test_status(const char *status, const char *test,
|
||||
const char *directive,
|
||||
const char *fmt_why, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt_why);
|
||||
|
||||
test_vstatus(status, test, directive, fmt_why, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
test_ok(const char *test)
|
||||
{
|
||||
test_status("ok", test, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
test_fail(const char *test)
|
||||
{
|
||||
test_status("not ok", test, NULL, NULL);
|
||||
++test_fail_count;
|
||||
}
|
||||
|
||||
void
|
||||
test_skip(const char *test, const char *fmt_why, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt_why);
|
||||
|
||||
test_vstatus("ok", test, "SKIP", fmt_why, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
test_todo(const char *test, const char *fmt_why, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt_why);
|
||||
|
||||
test_vstatus("not ok", test, "TODO", fmt_why, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
++test_fail_count;
|
||||
}
|
59
ext/fputils/tests/test_helper.h
Normal file
59
ext/fputils/tests/test_helper.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Andreas Sandberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _TEST_HELPER
|
||||
#define _TEST_HELPER 1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern unsigned test_current;
|
||||
extern unsigned test_count;
|
||||
extern unsigned test_fail_count;
|
||||
|
||||
void test_init(unsigned no_tests);
|
||||
void test_exit()
|
||||
__attribute__((noreturn));
|
||||
|
||||
void test_bail(const char *fmt, ...)
|
||||
__attribute__((format (printf, 1, 2), noreturn));
|
||||
|
||||
void test_diag(const char *fmt, ...)
|
||||
__attribute__((format (printf, 1, 2)));
|
||||
|
||||
void test_ok(const char *test);
|
||||
|
||||
void test_fail(const char *test);
|
||||
|
||||
void test_skip(const char *test, const char *fmt_why, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
|
||||
void test_todo(const char *test, const char *fmt_why, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue