1
2/*============================================================================
3
4This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
5Package, Release 3e, by John R. Hauser.
6
7Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
8University of California.  All rights reserved.
9
10Redistribution and use in source and binary forms, with or without
11modification, are permitted provided that the following conditions are met:
12
13 1. Redistributions of source code must retain the above copyright notice,
14    this list of conditions, and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright notice,
17    this list of conditions, and the following disclaimer in the documentation
18    and/or other materials provided with the distribution.
19
20 3. Neither the name of the University nor the names of its contributors may
21    be used to endorse or promote products derived from this software without
22    specific prior written permission.
23
24THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
25EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
27DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
28DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35=============================================================================*/
36
37
38/*============================================================================
39| Note:  If SoftFloat is made available as a general library for programs to
40| use, it is strongly recommended that a platform-specific version of this
41| header, "softfloat.h", be created that folds in "softfloat_types.h" and that
42| eliminates all dependencies on compile-time macros.
43*============================================================================*/
44
45
46#ifndef softfloat_h
47#define softfloat_h 1
48
49#include <stdbool.h>
50#include <stdint.h>
51#include "softfloat_types.h"
52
53#ifndef THREAD_LOCAL
54#define THREAD_LOCAL
55#endif
56
57/*----------------------------------------------------------------------------
58| Software floating-point underflow tininess-detection mode.
59*----------------------------------------------------------------------------*/
60enum {
61    softfloat_tininess_beforeRounding = 0,
62    softfloat_tininess_afterRounding  = 1
63};
64#define softfloat_detectTininess softfloat_tininess_afterRounding
65
66/*----------------------------------------------------------------------------
67| Software floating-point rounding mode.  (Mode "odd" is supported only if
68| SoftFloat is compiled with macro 'SOFTFLOAT_ROUND_ODD' defined.)
69*----------------------------------------------------------------------------*/
70enum {
71    softfloat_round_near_even   = 0,
72    softfloat_round_minMag      = 1,
73    softfloat_round_min         = 2,
74    softfloat_round_max         = 3,
75    softfloat_round_near_maxMag = 4,
76    softfloat_round_odd         = 6
77};
78
79/*----------------------------------------------------------------------------
80| Software floating-point exception flags.
81*----------------------------------------------------------------------------*/
82enum {
83    softfloat_flag_inexact   =  1,
84    softfloat_flag_underflow =  2,
85    softfloat_flag_overflow  =  4,
86    softfloat_flag_infinite  =  8,
87    softfloat_flag_invalid   = 16
88};
89
90#include "fp_emulation.h"
91
92/*----------------------------------------------------------------------------
93| Integer-to-floating-point conversion routines.
94*----------------------------------------------------------------------------*/
95float16_t ui32_to_f16( uint32_t );
96float32_t ui32_to_f32( uint32_t );
97float64_t ui32_to_f64( uint32_t );
98#ifdef SOFTFLOAT_FAST_INT64
99extFloat80_t ui32_to_extF80( uint32_t );
100float128_t ui32_to_f128( uint32_t );
101#endif
102void ui32_to_extF80M( uint32_t, extFloat80_t * );
103void ui32_to_f128M( uint32_t, float128_t * );
104float16_t ui64_to_f16( uint64_t );
105float32_t ui64_to_f32( uint64_t );
106float64_t ui64_to_f64( uint64_t );
107#ifdef SOFTFLOAT_FAST_INT64
108extFloat80_t ui64_to_extF80( uint64_t );
109float128_t ui64_to_f128( uint64_t );
110#endif
111void ui64_to_extF80M( uint64_t, extFloat80_t * );
112void ui64_to_f128M( uint64_t, float128_t * );
113float16_t i32_to_f16( int32_t );
114float32_t i32_to_f32( int32_t );
115float64_t i32_to_f64( int32_t );
116#ifdef SOFTFLOAT_FAST_INT64
117extFloat80_t i32_to_extF80( int32_t );
118float128_t i32_to_f128( int32_t );
119#endif
120void i32_to_extF80M( int32_t, extFloat80_t * );
121void i32_to_f128M( int32_t, float128_t * );
122float16_t i64_to_f16( int64_t );
123float32_t i64_to_f32( int64_t );
124float64_t i64_to_f64( int64_t );
125#ifdef SOFTFLOAT_FAST_INT64
126extFloat80_t i64_to_extF80( int64_t );
127float128_t i64_to_f128( int64_t );
128#endif
129void i64_to_extF80M( int64_t, extFloat80_t * );
130void i64_to_f128M( int64_t, float128_t * );
131
132/*----------------------------------------------------------------------------
133| 16-bit (half-precision) floating-point operations.
134*----------------------------------------------------------------------------*/
135uint_fast32_t f16_to_ui32( float16_t, uint_fast8_t, bool );
136uint_fast64_t f16_to_ui64( float16_t, uint_fast8_t, bool );
137int_fast32_t f16_to_i32( float16_t, uint_fast8_t, bool );
138int_fast64_t f16_to_i64( float16_t, uint_fast8_t, bool );
139uint_fast32_t f16_to_ui32_r_minMag( float16_t, bool );
140uint_fast64_t f16_to_ui64_r_minMag( float16_t, bool );
141int_fast32_t f16_to_i32_r_minMag( float16_t, bool );
142int_fast64_t f16_to_i64_r_minMag( float16_t, bool );
143float32_t f16_to_f32( float16_t );
144float64_t f16_to_f64( float16_t );
145#ifdef SOFTFLOAT_FAST_INT64
146extFloat80_t f16_to_extF80( float16_t );
147float128_t f16_to_f128( float16_t );
148#endif
149void f16_to_extF80M( float16_t, extFloat80_t * );
150void f16_to_f128M( float16_t, float128_t * );
151float16_t f16_roundToInt( float16_t, uint_fast8_t, bool );
152float16_t f16_add( float16_t, float16_t );
153float16_t f16_sub( float16_t, float16_t );
154float16_t f16_mul( float16_t, float16_t );
155float16_t f16_mulAdd( float16_t, float16_t, float16_t );
156float16_t f16_div( float16_t, float16_t );
157float16_t f16_rem( float16_t, float16_t );
158float16_t f16_sqrt( float16_t );
159bool f16_eq( float16_t, float16_t );
160bool f16_le( float16_t, float16_t );
161bool f16_lt( float16_t, float16_t );
162bool f16_eq_signaling( float16_t, float16_t );
163bool f16_le_quiet( float16_t, float16_t );
164bool f16_lt_quiet( float16_t, float16_t );
165bool f16_isSignalingNaN( float16_t );
166
167/*----------------------------------------------------------------------------
168| 32-bit (single-precision) floating-point operations.
169*----------------------------------------------------------------------------*/
170uint_fast32_t f32_to_ui32( float32_t, uint_fast8_t, bool );
171uint_fast64_t f32_to_ui64( float32_t, uint_fast8_t, bool );
172int_fast32_t f32_to_i32( float32_t, uint_fast8_t, bool );
173int_fast64_t f32_to_i64( float32_t, uint_fast8_t, bool );
174uint_fast32_t f32_to_ui32_r_minMag( float32_t, bool );
175uint_fast64_t f32_to_ui64_r_minMag( float32_t, bool );
176int_fast32_t f32_to_i32_r_minMag( float32_t, bool );
177int_fast64_t f32_to_i64_r_minMag( float32_t, bool );
178float16_t f32_to_f16( float32_t );
179float64_t f32_to_f64( float32_t );
180#ifdef SOFTFLOAT_FAST_INT64
181extFloat80_t f32_to_extF80( float32_t );
182float128_t f32_to_f128( float32_t );
183#endif
184void f32_to_extF80M( float32_t, extFloat80_t * );
185void f32_to_f128M( float32_t, float128_t * );
186float32_t f32_roundToInt( float32_t, uint_fast8_t, bool );
187float32_t f32_add( float32_t, float32_t );
188float32_t f32_sub( float32_t, float32_t );
189float32_t f32_mul( float32_t, float32_t );
190float32_t f32_mulAdd( float32_t, float32_t, float32_t );
191float32_t f32_div( float32_t, float32_t );
192float32_t f32_rem( float32_t, float32_t );
193float32_t f32_sqrt( float32_t );
194bool f32_eq( float32_t, float32_t );
195bool f32_le( float32_t, float32_t );
196bool f32_lt( float32_t, float32_t );
197bool f32_eq_signaling( float32_t, float32_t );
198bool f32_le_quiet( float32_t, float32_t );
199bool f32_lt_quiet( float32_t, float32_t );
200bool f32_isSignalingNaN( float32_t );
201uint_fast16_t f32_classify( float32_t a );
202
203/*----------------------------------------------------------------------------
204| 64-bit (double-precision) floating-point operations.
205*----------------------------------------------------------------------------*/
206uint_fast32_t f64_to_ui32( float64_t, uint_fast8_t, bool );
207uint_fast64_t f64_to_ui64( float64_t, uint_fast8_t, bool );
208int_fast32_t f64_to_i32( float64_t, uint_fast8_t, bool );
209int_fast64_t f64_to_i64( float64_t, uint_fast8_t, bool );
210uint_fast32_t f64_to_ui32_r_minMag( float64_t, bool );
211uint_fast64_t f64_to_ui64_r_minMag( float64_t, bool );
212int_fast32_t f64_to_i32_r_minMag( float64_t, bool );
213int_fast64_t f64_to_i64_r_minMag( float64_t, bool );
214float16_t f64_to_f16( float64_t );
215float32_t f64_to_f32( float64_t );
216#ifdef SOFTFLOAT_FAST_INT64
217extFloat80_t f64_to_extF80( float64_t );
218float128_t f64_to_f128( float64_t );
219#endif
220void f64_to_extF80M( float64_t, extFloat80_t * );
221void f64_to_f128M( float64_t, float128_t * );
222float64_t f64_roundToInt( float64_t, uint_fast8_t, bool );
223float64_t f64_add( float64_t, float64_t );
224float64_t f64_sub( float64_t, float64_t );
225float64_t f64_mul( float64_t, float64_t );
226float64_t f64_mulAdd( float64_t, float64_t, float64_t );
227float64_t f64_div( float64_t, float64_t );
228float64_t f64_rem( float64_t, float64_t );
229float64_t f64_sqrt( float64_t );
230bool f64_eq( float64_t, float64_t );
231bool f64_le( float64_t, float64_t );
232bool f64_lt( float64_t, float64_t );
233bool f64_eq_signaling( float64_t, float64_t );
234bool f64_le_quiet( float64_t, float64_t );
235bool f64_lt_quiet( float64_t, float64_t );
236bool f64_isSignalingNaN( float64_t );
237uint_fast16_t f64_classify( float64_t a );
238
239/*----------------------------------------------------------------------------
240| Rounding precision for 80-bit extended double-precision floating-point.
241| Valid values are 32, 64, and 80.
242*----------------------------------------------------------------------------*/
243extern THREAD_LOCAL uint_fast8_t extF80_roundingPrecision;
244
245/*----------------------------------------------------------------------------
246| 80-bit extended double-precision floating-point operations.
247*----------------------------------------------------------------------------*/
248#ifdef SOFTFLOAT_FAST_INT64
249uint_fast32_t extF80_to_ui32( extFloat80_t, uint_fast8_t, bool );
250uint_fast64_t extF80_to_ui64( extFloat80_t, uint_fast8_t, bool );
251int_fast32_t extF80_to_i32( extFloat80_t, uint_fast8_t, bool );
252int_fast64_t extF80_to_i64( extFloat80_t, uint_fast8_t, bool );
253uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t, bool );
254uint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t, bool );
255int_fast32_t extF80_to_i32_r_minMag( extFloat80_t, bool );
256int_fast64_t extF80_to_i64_r_minMag( extFloat80_t, bool );
257float16_t extF80_to_f16( extFloat80_t );
258float32_t extF80_to_f32( extFloat80_t );
259float64_t extF80_to_f64( extFloat80_t );
260float128_t extF80_to_f128( extFloat80_t );
261extFloat80_t extF80_roundToInt( extFloat80_t, uint_fast8_t, bool );
262extFloat80_t extF80_add( extFloat80_t, extFloat80_t );
263extFloat80_t extF80_sub( extFloat80_t, extFloat80_t );
264extFloat80_t extF80_mul( extFloat80_t, extFloat80_t );
265extFloat80_t extF80_div( extFloat80_t, extFloat80_t );
266extFloat80_t extF80_rem( extFloat80_t, extFloat80_t );
267extFloat80_t extF80_sqrt( extFloat80_t );
268bool extF80_eq( extFloat80_t, extFloat80_t );
269bool extF80_le( extFloat80_t, extFloat80_t );
270bool extF80_lt( extFloat80_t, extFloat80_t );
271bool extF80_eq_signaling( extFloat80_t, extFloat80_t );
272bool extF80_le_quiet( extFloat80_t, extFloat80_t );
273bool extF80_lt_quiet( extFloat80_t, extFloat80_t );
274bool extF80_isSignalingNaN( extFloat80_t );
275#endif
276uint_fast32_t extF80M_to_ui32( const extFloat80_t *, uint_fast8_t, bool );
277uint_fast64_t extF80M_to_ui64( const extFloat80_t *, uint_fast8_t, bool );
278int_fast32_t extF80M_to_i32( const extFloat80_t *, uint_fast8_t, bool );
279int_fast64_t extF80M_to_i64( const extFloat80_t *, uint_fast8_t, bool );
280uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *, bool );
281uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *, bool );
282int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *, bool );
283int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *, bool );
284float16_t extF80M_to_f16( const extFloat80_t * );
285float32_t extF80M_to_f32( const extFloat80_t * );
286float64_t extF80M_to_f64( const extFloat80_t * );
287void extF80M_to_f128M( const extFloat80_t *, float128_t * );
288void
289 extF80M_roundToInt(
290     const extFloat80_t *, uint_fast8_t, bool, extFloat80_t * );
291void extF80M_add( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
292void extF80M_sub( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
293void extF80M_mul( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
294void extF80M_div( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
295void extF80M_rem( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
296void extF80M_sqrt( const extFloat80_t *, extFloat80_t * );
297bool extF80M_eq( const extFloat80_t *, const extFloat80_t * );
298bool extF80M_le( const extFloat80_t *, const extFloat80_t * );
299bool extF80M_lt( const extFloat80_t *, const extFloat80_t * );
300bool extF80M_eq_signaling( const extFloat80_t *, const extFloat80_t * );
301bool extF80M_le_quiet( const extFloat80_t *, const extFloat80_t * );
302bool extF80M_lt_quiet( const extFloat80_t *, const extFloat80_t * );
303bool extF80M_isSignalingNaN( const extFloat80_t * );
304
305/*----------------------------------------------------------------------------
306| 128-bit (quadruple-precision) floating-point operations.
307*----------------------------------------------------------------------------*/
308#ifdef SOFTFLOAT_FAST_INT64
309uint_fast32_t f128_to_ui32( float128_t, uint_fast8_t, bool );
310uint_fast64_t f128_to_ui64( float128_t, uint_fast8_t, bool );
311int_fast32_t f128_to_i32( float128_t, uint_fast8_t, bool );
312int_fast64_t f128_to_i64( float128_t, uint_fast8_t, bool );
313uint_fast32_t f128_to_ui32_r_minMag( float128_t, bool );
314uint_fast64_t f128_to_ui64_r_minMag( float128_t, bool );
315int_fast32_t f128_to_i32_r_minMag( float128_t, bool );
316int_fast64_t f128_to_i64_r_minMag( float128_t, bool );
317float16_t f128_to_f16( float128_t );
318float32_t f128_to_f32( float128_t );
319float64_t f128_to_f64( float128_t );
320extFloat80_t f128_to_extF80( float128_t );
321float128_t f128_roundToInt( float128_t, uint_fast8_t, bool );
322float128_t f128_add( float128_t, float128_t );
323float128_t f128_sub( float128_t, float128_t );
324float128_t f128_mul( float128_t, float128_t );
325float128_t f128_mulAdd( float128_t, float128_t, float128_t );
326float128_t f128_div( float128_t, float128_t );
327float128_t f128_rem( float128_t, float128_t );
328float128_t f128_sqrt( float128_t );
329bool f128_eq( float128_t, float128_t );
330bool f128_le( float128_t, float128_t );
331bool f128_lt( float128_t, float128_t );
332bool f128_eq_signaling( float128_t, float128_t );
333bool f128_le_quiet( float128_t, float128_t );
334bool f128_lt_quiet( float128_t, float128_t );
335bool f128_isSignalingNaN( float128_t );
336#endif
337uint_fast32_t f128M_to_ui32( const float128_t *, uint_fast8_t, bool );
338uint_fast64_t f128M_to_ui64( const float128_t *, uint_fast8_t, bool );
339int_fast32_t f128M_to_i32( const float128_t *, uint_fast8_t, bool );
340int_fast64_t f128M_to_i64( const float128_t *, uint_fast8_t, bool );
341uint_fast32_t f128M_to_ui32_r_minMag( const float128_t *, bool );
342uint_fast64_t f128M_to_ui64_r_minMag( const float128_t *, bool );
343int_fast32_t f128M_to_i32_r_minMag( const float128_t *, bool );
344int_fast64_t f128M_to_i64_r_minMag( const float128_t *, bool );
345float16_t f128M_to_f16( const float128_t * );
346float32_t f128M_to_f32( const float128_t * );
347float64_t f128M_to_f64( const float128_t * );
348void f128M_to_extF80M( const float128_t *, extFloat80_t * );
349void f128M_roundToInt( const float128_t *, uint_fast8_t, bool, float128_t * );
350void f128M_add( const float128_t *, const float128_t *, float128_t * );
351void f128M_sub( const float128_t *, const float128_t *, float128_t * );
352void f128M_mul( const float128_t *, const float128_t *, float128_t * );
353void
354 f128M_mulAdd(
355     const float128_t *, const float128_t *, const float128_t *, float128_t *
356 );
357void f128M_div( const float128_t *, const float128_t *, float128_t * );
358void f128M_rem( const float128_t *, const float128_t *, float128_t * );
359void f128M_sqrt( const float128_t *, float128_t * );
360bool f128M_eq( const float128_t *, const float128_t * );
361bool f128M_le( const float128_t *, const float128_t * );
362bool f128M_lt( const float128_t *, const float128_t * );
363bool f128M_eq_signaling( const float128_t *, const float128_t * );
364bool f128M_le_quiet( const float128_t *, const float128_t * );
365bool f128M_lt_quiet( const float128_t *, const float128_t * );
366bool f128M_isSignalingNaN( const float128_t * );
367
368#endif
369
370