Berkeley TestFloat Release 3e: Source Documentation

John R. Hauser
2018 January 20

Contents

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 Program
6.5. Improving the Random Number Functions
7. Contact Information

1. Introduction

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 64-bit integers. If the all-in-one 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.

Release 3 of TestFloat was a complete rewrite relative to Release 2c or earlier. The current version of TestFloat is Release 3e.

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.

2. Limitations

TestFloat assumes the computer has an addressable byte size of either 8 or 16 bits. (Nearly all computers in use today have 8-bit bytes.)

TestFloat is written entirely in C. The C compiler used must conform at a minimum to the 1989 ANSI standard for the C language (same as the 1990 ISO standard) and must in addition support basic arithmetic on 64-bit integers. Earlier releases of TestFloat were capable of testing 32-bit single-precision and 64-bit double-precision floating-point without requiring compiler support for 64-bit integers, but this option is not supported starting with Release 3. Since 1999, ISO standards for C have mandated compiler support for 64-bit integers. A compiler conforming to the 1999 C Standard or later is recommended but not strictly required.

C Standard header files <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 section 6.1, Standard Headers <stdbool.h> and <stdint.h>.

3. Acknowledgments and License

The TestFloat package was written by me, John R. Hauser. Release 3 of TestFloat was a completely new implementation supplanting earlier releases. The project to create Release 3 (now through 3e) was done in the employ of the University of California, Berkeley, within the Department of Electrical Engineering and Computer Sciences, first for the Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab. The work was officially overseen by Prof. Krste Asanovic, with funding provided by these sources:

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 Release 3e as well as to each source file individually.

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:

  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.

  3. 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.

4. TestFloat Package Directory Structure

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:

doc
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
The majority of the TestFloat sources are provided in the source directory. The subj-C subdirectory contains the sources that configure the all-in-one 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 is an abbreviation of subject, referring to the floating-point that is the subject of the test. If testfloat is retargeted to test other floating-point implementations, the corresponding source files would be expected to be in other subdirectories alongside subj-C, with names of the form subj-<target>. More about retargeting testfloat is found in section 6.4, Specializing the 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>. For the example targets, <execution-environment> is Linux-386, Linux-386-SSE2, Linux-x86_64, Linux-ARM-VFPv2, Win32, Win32-SSE2, or Win64, and <compiler> is 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:

Makefile
platform.h
The provided 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.

5. Dependence on Berkeley SoftFloat

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. The SoftFloat library must be compiled before the TestFloat programs can be built. In the example Makefiles, the locations of the SoftFloat header files and pre-compiled library are specified by these macros:

SOFTFLOAT_INCLUDE_DIR
The path of the directory containing softfloat.h, as well as other nonstandard header files referenced by softfloat.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 by softfloat.h, such as softfloat_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 or libsoftfloat.a).

6. Issues for Porting TestFloat to a New Target

6.1. Standard Headers <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>:

bool
true
false
and on these names from <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

6.2. Standard Header <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 section 6.4 below, Specializing the testfloat Program.

6.3. Macros for Build Options

The TestFloat source files are affected by several C preprocessor macros:

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 of inline, this macro may need to be defined to extern 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 variables softfloat_roundingMode, softfloat_detectTininess, extF80_roundingPrecision, and softfloat_exceptionFlags. To use the supplied, unmodified header softfloat.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.
Following the usual custom for C, for all the macros except 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).

6.4. Specializing the 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:

LONG_DOUBLE_IS_EXTFLOAT80
Indicates that type long double is 80-bit double-extended-precision floating-point.
LONG_DOUBLE_IS_FLOAT128
Indicates that type long double is 128-bit quadruple-precision floating-point.
By default, 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:

subjfloat_config.h
subjfloat.c
For the default target of testing C’s floating-point, these files are contained in directory source/subj-C as discussed earlier. For a different subject floating-point, it is recommended that appropriate versions of subjfloat_config.h and subjfloat.c be stored in a sibling subj-<target> directory, where <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 32-bit floating-point addition, then 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, so these macros can be ignored for any other subject floating-point that does not depend on them. On the other hand, macros 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.

6.5. Improving the Random Number Functions

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.

7. Contact Information

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.