Berkeley SoftFloat Source Documentation

# Berkeley SoftFloat Release 3e: Source Documentation

John R. Hauser
2018 January 20

## Contents

> 1. Introduction
> 2. Limitations
> 3. Acknowledgments and License
> 4. SoftFloat Package Directory Structure
> 5. Issues for Porting SoftFloat to a New Target
> | 5.1. Standard Headers `<stdbool.h>` and `<stdint.h>`
> | 5.2. Specializing Floating-Point Behavior
> | 5.3. Macros for Build Options
> | 5.4. Adapting a Template Target Directory
> | 5.5. Target-Specific Optimization of Primitive Functions
> 6. Testing SoftFloat
> 7. Providing SoftFloat as a Common Library for Applications
> 8. Contact Information

## 1. Introduction

This document gives information needed for compiling and/or porting Berkeley SoftFloat, a library of C functions implementing binary floating-point conforming to the IEEE Standard for Floating-Point Arithmetic. For basic documentation about SoftFloat refer to `SoftFloat.html`.

The source code for SoftFloat is intended to be relatively machine-independent and should be compilable with any ISO-Standard C compiler that also supports 64-bit integers. SoftFloat has been successfully compiled with the GNU C Compiler (`gcc`) for several platforms.

Release 3 of SoftFloat was a complete rewrite relative to Release 2 or earlier. Changes to the interface of SoftFloat functions are documented in `SoftFloat.html`. The current version of SoftFloat is Release 3e.

## 2. Limitations

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

SoftFloat is written in C and is designed to work with other C code. 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 SoftFloat included implementations of 32-bit single-precision and 64-bit double-precision floating-point that did not require 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. SoftFloat’s dependence on these headers is detailed later in section 5.1, Standard Headers `<stdbool.h>` and `<stdint.h>`.

## 3. Acknowledgments and License

The SoftFloat package was written by me, John R. Hauser. Release 3 of SoftFloat 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 SoftFloat 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. SoftFloat Package Directory Structure

Because SoftFloat 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
>         include
>         8086
>         8086-SSE
>         ARM-VFPv2
>         ARM-VFPv2-defaultNaN
>     build
>         template-FAST_INT64
>         template-not-FAST_INT64
>         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 SoftFloat sources are provided in the `source` directory. The `include` subdirectory contains several header files (unsurprisingly), while the other subdirectories of `source` contain source files that specialize the floating-point behavior to match particular processor families:

> `8086`
>   Intel’s older, 8087-derived floating-point, extended to all supported floating-point types
> `8086-SSE`
>   Intel’s x86 processors with Streaming SIMD Extensions (SSE) and later compatible extensions, having 8087 behavior for 80-bit double-extended-precision (`extFloat80_t`) and SSE behavior for other floating-point types
> `ARM-VFPv2`
>   ARM’s VFPv2 or later floating-point, with NaN payload propagation
> `ARM-VFPv2-defaultNaN`
>   ARM’s VFPv2 or later floating-point, with the “default NaN” option

If other specializations are attempted, these would be expected to be other subdirectories of `source` alongside the ones listed above. Specialization is covered later, in section 5.2, Specializing Floating-Point Behavior.

The `build` directory is intended to contain a subdirectory for each target platform for which a build of the SoftFloat library may be created. For each build target, the target’s subdirectory is where all derived object files and the completed SoftFloat library (typically `softfloat.a` or `libsoftfloat.a`) are created. The two `template` subdirectories are not actual build targets but contain sample files for creating new target directories. (The meaning of `FAST_INT64` will be explained later.)

Ignoring the `template` directories, 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. Despite requests, there are currently no plans to include and maintain in the SoftFloat 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 SoftFloat 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 SoftFloat 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. At the other extreme, to get maximal performance from SoftFloat, it may be desirable to include in header `platform.h` (directly or via `#include`) declarations for numerous target-specific optimizations. Such possibilities are discussed in the next section, Issues for Porting SoftFloat to a New Target. If the target’s compiler or library has bugs or other shortcomings, workarounds for these issues may also be possible with target-specific declarations in `platform.h`, avoiding the need to modify the main SoftFloat sources.

## 5. Issues for Porting SoftFloat to a New Target

### 5.1. Standard Headers `<stdbool.h>` and `<stdint.h>`

The SoftFloat 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. SoftFloat 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

### 5.2. Specializing Floating-Point Behavior

The IEEE Floating-Point Standard allows for some flexibility in a conforming implementation, particularly concerning NaNs. The SoftFloat `source` directory is supplied with some specialization subdirectories containing possible definitions for this implementation-specific behavior. For example, the `8086` and `8086-SSE` subdirectories have source files that specialize SoftFloat’s behavior to match that of Intel’s x86 line of processors. The files in a specialization subdirectory must determine:

- whether tininess for underflow is detected before or after rounding by default;
- how signaling NaNs are distinguished from quiet NaNs;
- what (if anything) special happens when exceptions are raised;
- the default generated quiet NaNs;
- how NaNs are propagated from function inputs to output; and
- the integer results returned when conversions to integer type raise the invalid exception.

As provided, the build process for a target expects to involve exactly one specialization directory that defines all of these implementation-specific details for the target. A specialization directory such as `8086` is expected to contain a header file called `specialize.h`, together with whatever other source files are needed to complete the specialization.

A new build target may use an existing specialization, such as the ones provided by the `8086` and `8086-SSE` subdirectories. If a build target needs a new specialization, different from any existing ones, it is recommended that a new specialization directory be created for this purpose. The `specialize.h` header file from any of the provided specialization subdirectories can be used as a model for what definitions are needed.

### 5.3. Macros for Build Options

The SoftFloat source files adapt the floating-point implementation according to several C preprocessor macros:

> `LITTLEENDIAN`
>   Must be defined for little-endian machines; must not be defined for big-endian machines.
> `INLINE`
>   Specifies the sequence of tokens used to indicate that a C function should be inlined. If macro `INLINE_LEVEL` is defined with a value of 1 or higher, this macro must be defined; otherwise, this macro is ignored and need 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 header `softfloat.h` in the declarations of variables `softfloat_roundingMode`, `softfloat_detectTininess`, `extF80_roundingPrecision`, and `softfloat_exceptionFlags`. If macro `THREAD_LOCAL` is left undefined, these variables will default to being ordinary global variables. Depending on the compiler, possible valid definitions of this macro include `_Thread_local` and `__thread`.
> `SOFTFLOAT_ROUND_ODD`
>   Can be defined to enable support for optional rounding mode `softfloat_round_odd`.
> `INLINE_LEVEL`
>   Can be defined to an integer to determine the degree of inlining requested of the compiler. Larger numbers request that more inlining be done. If this macro is not defined or is defined to a value less than 1 (zero or negative), no inlining is requested. The maximum effective value is no higher than 5. Defining this macro to a value greater than 5 is the same as defining it to 5.
> `SOFTFLOAT_FAST_INT64`
>   Can be defined to indicate that the build target’s implementation of 64-bit arithmetic is efficient. For newer 64-bit processors, this macro should usually be defined. For very small microprocessors whose buses and registers are 8-bit or 16-bit in size, this macro should usually not be defined. Whether this macro should be defined for a 32-bit processor may depend on the target machine and the applications that will use SoftFloat.
> `SOFTFLOAT_FAST_DIV32TO16`
>   Can be defined to indicate that the target’s division operator in C (written as `/`) is reasonably efficient for dividing a 32-bit unsigned integer by a 16-bit unsigned integer. Setting this macro may affect the performance of function `f16_div`.
> `SOFTFLOAT_FAST_DIV64TO32`
>   Can be defined to indicate that the target’s division operator in C (written as `/`) is reasonably efficient for dividing a 64-bit unsigned integer by a 32-bit unsigned integer. Setting this macro may affect the performance of division, remainder, and square root operations other than `f16_div`.

Following the usual custom for C, for most of these macros (all except `INLINE`, `THREAD_LOCAL`, and `INLINE_LEVEL`), the content of any definition is irrelevant; what matters is a macro’s effect on `#ifdef` directives.

It is recommended that any definitions 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 options and control optimization, and thus might be better located in the target’s Makefile (or its equivalent).

### 5.4. Adapting a Template Target Directory

In the `build` directory, two `template` subdirectories provide models for new target directories. Two different templates exist because different functions are needed in the SoftFloat library depending on whether macro `SOFTFLOAT_FAST_INT64` is defined. If macro `SOFTFLOAT_FAST_INT64` will be defined, `template-FAST_INT64` is the template to use; otherwise, `template-not-FAST_INT64` is the appropriate template. A new target directory can be created by copying the correct template directory and editing the files inside. To avoid confusion, it would be wise to refrain from editing the files within a template directory directly.

### 5.5. Target-Specific Optimization of Primitive Functions

Header file `primitives.h` (in directory `source/include`) declares macros and functions for numerous underlying arithmetic operations upon which many of SoftFloat’s floating-point functions are ultimately built. The SoftFloat sources include implementations of all of these functions/macros, written as standard C code, so a complete and correct SoftFloat library can be created using only the supplied code for all functions. However, for many targets, SoftFloat’s performance can be improved by substituting target-specific implementations of some of the functions/macros declared in `primitives.h`.

For example, `primitives.h` declares a function called `softfloat_countLeadingZeros32` that takes an unsigned 32-bit integer as an argument and returns the number of the integer’s most-significant bits that are zeros. While the SoftFloat sources include an implementation of this function written in standard C, many processors can perform this same function directly in only one or two machine instructions. An alternative, target-specific implementation that maps to those instructions is likely to be more efficient than the generic C code from the SoftFloat package.

A build target can replace the supplied version of any function or macro of `primitives.h` by defining a macro with the same name in the target’s `platform.h` header file. For this purpose, it may be helpful for `platform.h` to `#include` header file `primitiveTypes.h`, which defines types used for arguments and results of functions declared in `primitives.h`. When a desired replacement implementation is a function, not a macro, it is sufficient for `platform.h` to include the line

>     #define <function-name> <function-name>

where `<function-name>` is the name of the function. This technically defines `<function-name>` as a macro, but one that resolves to the same name, which may then be a function. (A preprocessor that conforms to the C Standard is required to limit recursive macro expansion from being applied more than once.)

The supplied header file `opts-GCC.h` (in directory `source/include`) provides an example of target-specific optimization for the GCC compiler. Each GCC target example in the `build` directory has

> `#include "opts-GCC.h"`

in its `platform.h` header file. Before `opts-GCC.h` is included, the following macros must be defined (or not) to control which features are invoked:

> `SOFTFLOAT_BUILTIN_CLZ`
>   If defined, SoftFloat’s internal ‘`countLeadingZeros`’ functions use intrinsics `__builtin_clz` and `__builtin_clzll`.
> `SOFTFLOAT_INTRINSIC_INT128`
>   If defined, SoftFloat makes use of GCC’s nonstandard 128-bit integer type `__int128`.

On some machines, these improvements are observed to increase the speeds of `f64_mul` and `f128_mul` by around 20 to 25%, although other functions receive less dramatic boosts, or none at all. Results can vary greatly across different platforms.

## 6. Testing SoftFloat

SoftFloat can be tested using the `testsoftfloat` program by the same author. This program is part of the Berkeley TestFloat package available at the Web page `http://www.jhauser.us/arithmetic/TestFloat.html`. The TestFloat package also has a program called `timesoftfloat` that measures the speed of SoftFloat’s floating-point functions.

## 7. Providing SoftFloat as a Common Library for Applications

Header file `softfloat.h` defines the SoftFloat interface as seen by clients. If the SoftFloat library will be made a common library for programs on a system, the supplied `softfloat.h` has a couple of deficiencies for this purpose:

- As supplied, `softfloat.h` depends on another header, `softfloat_types.h`, that is not intended for public use but which must also be visible to the programmer’s compiler.
- More troubling, at the time `softfloat.h` is included in a C source file, macros `SOFTFLOAT_FAST_INT64` and `THREAD_LOCAL` must be defined, or not defined, consistent with how these macro were defined when the SoftFloat library was built.

In the situation that new programs may regularly `#include` header file `softfloat.h`, it is recommended that a custom, self-contained version of this header file be created that eliminates these issues.

## 8. Contact Information

At the time of this writing, the most up-to-date information about SoftFloat and the latest release can be found at the Web page `http://www.jhauser.us/arithmetic/SoftFloat.html`.