John R. Hauser
2018 January 20
1. Introduction 2. Limitations 3. Acknowledgments and License 4. TestFloat Package Directory Structure 5. Dependence on Berkeley SoftFloat 6. Issues for Porting TestFloat to a New Target 6.1. Standard Headers <stdbool.h>
and<stdint.h>
6.2. Standard Header <fenv.h>
6.3. Macros for Build Options 6.4. Specializing the testfloat
Program6.5. Improving the Random Number Functions 7. Contact Information
This document gives information needed for compiling and/or porting Berkeley
TestFloat, a small collection of programs for testing that an implementation of
binary floating-point conforms to the IEEE Standard for Floating-Point
Arithmetic.
For basic documentation about TestFloat refer to
TestFloat-general.html
The source code for TestFloat is intended to be relatively machine-independent.
Most programs in the TestFloat package should be compilable with any
ISO-Standard C compiler that also supports testfloat
program will be used to test a new
floating-point implementation, additional effort will likely be required to
retarget that program to invoke the new floating-point operations.
TestFloat has been successfully compiled with the GNU C Compiler
(gcc
) for several platforms.
TestFloat depends on Berkeley SoftFloat, which is a software implementation of
binary floating-point that conforms to the IEEE Standard for Floating-Point
Arithmetic.
SoftFloat is not included with the TestFloat sources.
It can be obtained from the Web page
http://www.jhauser.us/arithmetic/SoftFloat.html
TestFloat assumes the computer has an addressable byte size of either 8 or
TestFloat is written entirely
<stdbool.h>
and
<stdint.h>
are required for defining standard Boolean and
integer types.
If these headers are not supplied with the C compiler, minimal substitutes must
be provided.
TestFloat’s dependence on these headers is detailed later in
<stdbool.h>
and <stdint.h>
.
The TestFloat package was written by me,
Par Lab: Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery (Award #DIG07-10227), with additional support from Par Lab affiliates Nokia, NVIDIA, Oracle, and Samsung. ASPIRE Lab: DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA, Oracle, and Samsung.
The following applies to the whole of TestFloat
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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.
Because TestFloat is targeted to multiple platforms, its source code is slightly scattered between target-specific and target-independent directories and files. The supplied directory structure is as follows:
The majority of the TestFloat sources are provided in thedoc source subj-C build template Linux-386-GCC Linux-386-SSE2-GCC Linux-x86_64-GCC Linux-ARM-VFPv2-GCC Win32-MinGW Win32-SSE2-MinGW Win64-MinGW-w64
source
directory.
The subj-C
testfloat
program to test the C
compiler’s implementation of the standard C types float
,
double
, and possibly long
double
.
The ‘subj
’ in subj-C
testfloat
is retargeted to test other floating-point
implementations, the corresponding source files would be expected to be in
other subdirectories alongside subj-C
subj-<target>
testfloat
is found in
testfloat
Program.
The build
directory is intended to contain a subdirectory for each
target platform for which builds of the TestFloat programs may be created.
For each build target, the target’s subdirectory is where all derived
object files and the completed TestFloat executables are created.
The template
subdirectory is not an actual build target but
contains sample files for creating new target directories.
Ignoring the template
directory, the supplied target directories
are intended to follow a naming system of
<execution-environment>-<compiler>
<execution-environment>
Linux-386
Linux-386-SSE2
Linux-x86_64
Linux-ARM-VFPv2
Win32
,
Win32-SSE2
Win64
, and
<compiler>
GCC
,
MinGW
, or MinGW-w64
All of the supplied target directories are merely examples that may or may not be correct for compiling on any particular system. There are currently no plans to include and maintain in the TestFloat package the build files needed for a great many users’ compilation environments, which can span a huge range of operating systems, compilers, and other tools.
As supplied, each target directory contains two files:
The providedMakefile platform.h
Makefile
is written for GNU make
.
A build of TestFloat for the specific target is begun by executing the
make
command with the target directory as the current directory.
A completely different build tool can be used if an appropriate
Makefile
equivalent is created.
The platform.h
header file exists to provide a location for
additional C declarations specific to the build target.
Every C source file of TestFloat contains a #include
for
platform.h
.
In many cases, the contents of platform.h
can be as simple as one
or two lines of code.
If the target’s compiler or library has bugs or other shortcomings,
workarounds for these issues may be possible with target-specific declarations
in platform.h
, without the need to modify the main TestFloat
sources.
It may not be necessary to build all of the TestFloat programs.
For testing a floating-point implementation, typically
testfloat_gen
and testfloat
will not both be used,
and testfloat_ver
may not be needed either.
The Makefile (or equivalent) can be modified not to create unneeded programs.
This may be especially relevant for the all-in-one test program
testfloat
, which might not build without special attention.
In addition to the distributed sources, TestFloat depends on the existence of a
compatible Berkeley SoftFloat library and the corresponding header file
softfloat.h
.
As mentioned earlier, SoftFloat is a separate package available at Web page
http://www.jhauser.us/arithmetic/SoftFloat.html
SOFTFLOAT_INCLUDE_DIR
- The path of the directory containing
softfloat.h
, as well as other nonstandard header files referenced bysoftfloat.h
, if any.SOFTFLOAT_H
- A list of the full paths of all SoftFloat header files needed by SoftFloat clients. This list must include
softfloat.h
and may also include other header files referenced bysoftfloat.h
, such assoftfloat_types.h
. This macro is used only to establish build dependencies between the SoftFloat header files and TestFloat’s source files, in case the SoftFloat header files are changed.SOFTFLOAT_LIB
- The full path of the compiled SoftFloat library (usually
softfloat.a
orlibsoftfloat.a
).
<stdbool.h>
and <stdint.h>
The TestFloat sources make use of standard headers
<stdbool.h>
and <stdint.h>
, which have
been part of the ISO C Standard Library since 1999.
With any recent compiler, these standard headers are likely to be supported,
even if the compiler does not claim complete conformance to the latest ISO C
Standard.
For older or nonstandard compilers, substitutes for
<stdbool.h>
and <stdint.h>
may need to be
created.
TestFloat depends on these names from <stdbool.h>
:
and on these names frombool true false
<stdint.h>
:
uint16_t uint32_t uint64_t int32_t int64_t UINT64_C INT64_C uint_least8_t uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t int_fast8_t int_fast16_t int_fast32_t int_fast64_t
<fenv.h>
Because the supplied all-in-one testfloat
program tests the
floating-point operations of the C language, it uses the facilities provided by
standard C header <fenv.h>
to access the floating-point
environment of C, in particular to set the rounding mode and to access the
floating-point exception flags.
Like <stdbool.h>
and <stdint.h>
,
<fenv.h>
has been part of the ISO C Standard Library since
1999, but older or nonstandard C compilers may not support it.
Some form of standard header <fenv.h>
is needed only if the
testfloat
program is wanted and the program will not be
retargeted to invoke a floating-point implementation in a way that bypasses the
standard C environment.
Typically, if testfloat
is wanted, it will be retargeted to invoke
a new floating-point implementation directly, making
<fenv.h>
irrelevant.
For more about retargeting testfloat
, see testfloat
Program.
The TestFloat source files are affected by several C preprocessor macros:
Following the usual custom
LITTLEENDIAN
- Must be defined for little-endian machines; must not be defined for big-endian machines.
INLINE
- Can be defined to a sequence of tokens used to indicate that a C function should be inlined. If the compiler does not support the inlining of functions, this macro must not be defined. For compilers that conform to the C Standard’s rules for inline functions, this macro can be defined as the single keyword
inline
. For other compilers that follow a convention pre-dating the standardization ofinline
, this macro may need to be defined toextern
inline
.THREAD_LOCAL
- Can be defined to a sequence of tokens that, when appearing at the start of a variable declaration, indicates to the C compiler that the variable is per-thread, meaning that each execution thread gets its own separate instance of the variable. This macro is used in the supplied version of Berkeley SoftFloat’s header
softfloat.h
, in the declarations of variablessoftfloat_roundingMode
,softfloat_detectTininess
,extF80_roundingPrecision
, andsoftfloat_exceptionFlags
. To use the supplied, unmodified headersoftfloat.h
, this macro must be defined (or not defined) the same as when the SoftFloat library was built.
FLOAT16
- Must be defined if the TestFloat programs are to support the
16-bit half-precision floating-point format.FLOAT64
- Must be defined if the TestFloat programs are to support the
64-bit double-precision floating-point format.EXTFLOAT80
- Must be defined if the TestFloat programs are to support the
80-bit double-extended-precision floating-point format.FLOAT128
- Must be defined if the TestFloat programs are to support the
128-bit quadruple-precision floating-point format.FLOAT_ROUND_ODD
- Must be defined if the TestFloat programs are to support rounding to odd (jamming). To be useful, this option also requires that the Berkeley SoftFloat library was compiled with macro
SOFTFLOAT_ROUND_ODD
defined.
INLINE
and THREAD_LOCAL
, the content of a
macro’s definition is irrelevant;
what matters is a macro’s effect on #ifdef
directives.
It is recommended that any definition of macros LITTLEENDIAN
,
INLINE
, and THREAD_LOCAL
be made in a build
target’s platform.h
header file, because these macros are
expected to be determined inflexibly by the target machine and compiler.
The other five macros select build options, and hence might be better located
in the target’s Makefile (or its equivalent).
testfloat
Program
The supplied sources for the all-in-one testfloat
program cause
testfloat
to test the C compiler’s float
and
double
types for C operations +
, -
,
*
, /
, etc.
The supplied version is also capable of testing C type long
double
if the sources are compiled with one of these macros
defined:
By default,
LONG_DOUBLE_IS_EXTFLOAT80
- Indicates that type
long
double
is80-bit double-extended-precision floating-point.LONG_DOUBLE_IS_FLOAT128
- Indicates that type
long
double
is128-bit quadruple-precision floating-point.
testfloat
assumes that only the IEEE Standard’s
original four rounding modes (near_even
, minMag
,
min
, and max
) are supported by the floating-point
being tested.
For other rounding modes, additional macro can be defined:
SUBJFLOAT_ROUND_NEAR_MAXMAG
- Indicates that the subject floating-point supports rounding mode
near_maxMag
(nearest/away).SUBJFLOAT_ROUND_ODD
- Indicates that the subject floating-point supports rounding mode
odd
(jamming).
To test a new and/or different implementation of floating-point,
testfloat
must normally be retargeted to invoke this other
floating-point instead of C’s floating-point.
Two source files define the functions that testfloat
uses to
invoke floating-point operations for testing:
For the default target of testing C’s floating-point, these files are contained in directorysubjfloat_config.h subjfloat.c
source/subj-C
subjfloat_config.h
and subjfloat.c
be
stored in a sibling subj-<target>
<target>
names the particular
target.
Header file subjfloat_config.h
defines a macro of the form
SUBJ_*
for each subject function supported.
For example, if function subj_f32_add
exists to perform
subjfloat_config.h
should have a definition for macro
SUBJ_F32_ADD
.
The actual function subj_f32_add
is expected to be defined in
subjfloat.c
, along with all other subject functions.
A common header file, subjfloat.h
, (not target-specific) provides
prototype declarations for all possible subject functions that
testfloat
may be compiled to test, whether actually existing or
not.
(There is no penalty for the header to declare prototypes of nonexistent
functions that are never called.)
For a specific build of testfloat
, the -list
option
will list all subject functions that the testfloat
program is able
to invoke and thus test.
In the source code as supplied, macros LONG_DOUBLE_IS_EXTFLOAT80
and LONG_DOUBLE_IS_FLOAT128
affect only the target-specific source
files in source/subj-C
SUBJFLOAT_ROUND_NEAR_MAXMAG
and
SUBJFLOAT_ROUND_ODD
always determine whether the
testfloat
program attempts to test rounding modes
near_maxMag
and odd
, regardless of the subject
floating-point.
If you are serious about using TestFloat for testing floating-point, you should
consider replacing the random number functions in random.c
.
The supplied random number functions are built on top of the standard C
rand
function.
Because function rand
is rather poor on some systems, the
functions in random.c
assume very little about the quality of
rand
.
As a result, rand
is called more frequently than it might need to
be, shortening the time before random number sequences repeat, and possibly
wasting time as well.
If rand
is better on a given target platform, or if another,
better random number generator is available (such as rand48
on
UNIX-derived systems), TestFloat can be improved by overriding the given
random.c
with a target-specific one.
Rather than modifying the supplied file random.c
, it is
recommended instead that a new, alternate file be created and the
target’s Makefile be modified to refer to that alternate file in place of
random.c
.
At the time of this writing, the most up-to-date information about TestFloat
and the latest release can be found at the Web page
http://www.jhauser.us/arithmetic/TestFloat.html