xref: /netbsd-src/regress/lib/libc/ieeefp/testfloat/include/softfloat.h (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: softfloat.h,v 1.5 2008/04/28 20:23:04 martin Exp $	*/
2 
3 /* This is a derivative work. */
4 
5 /*-
6  * Copyright (c) 2001 The NetBSD Foundation, Inc.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to The NetBSD Foundation
10  * by Ross Harvey.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35 ===============================================================================
36 
37 This C header file is part of the SoftFloat IEC/IEEE Floating-point
38 Arithmetic Package, Release 2a.
39 
40 Written by John R. Hauser.  This work was made possible in part by the
41 International Computer Science Institute, located at Suite 600, 1947 Center
42 Street, Berkeley, California 94704.  Funding was partially provided by the
43 National Science Foundation under grant MIP-9311980.  The original version
44 of this code was written as part of a project to build a fixed-point vector
45 processor in collaboration with the University of California at Berkeley,
46 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
47 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
48 arithmetic/SoftFloat.html'.
49 
50 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
51 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
52 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
53 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
54 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
55 
56 Derivative works are acceptable, even for commercial purposes, so long as
57 (1) they include prominent notice that the work is derivative, and (2) they
58 include prominent notice akin to these four paragraphs for those parts of
59 this code that are retained.
60 
61 ===============================================================================
62 */
63 
64 #include <ieeefp.h>
65 #include <inttypes.h>
66 #include <sys/endian.h>
67 
68 /*
69 -------------------------------------------------------------------------------
70 The macro `FLOATX80' must be defined to enable the extended double-precision
71 floating-point format `floatx80'.  If this macro is not defined, the
72 `floatx80' type will not be defined, and none of the functions that either
73 input or output the `floatx80' type will be defined.  The same applies to
74 the `FLOAT128' macro and the quadruple-precision format `float128'.
75 -------------------------------------------------------------------------------
76 */
77 /* #define FLOATX80 */
78 /* #define FLOAT128 */
79 
80 /*
81 -------------------------------------------------------------------------------
82 Software IEC/IEEE floating-point types.
83 -------------------------------------------------------------------------------
84 */
85 typedef uint32_t float32;
86 typedef uint64_t float64;
87 #ifdef FLOATX80
88 typedef struct {
89 #if BYTE_ORDER == BIG_ENDIAN
90     uint16_t high;
91     uint64_t low;
92 #else
93     uint64_t low;
94     uint16_t high;
95 #endif
96 } floatx80;
97 #endif
98 #ifdef FLOAT128
99 typedef struct {
100     uint64_t high, low;
101 } float128;
102 #endif
103 
104 /*
105 -------------------------------------------------------------------------------
106 Software IEC/IEEE floating-point underflow tininess-detection mode.
107 -------------------------------------------------------------------------------
108 */
109 extern int float_detect_tininess;
110 enum {
111     float_tininess_after_rounding  = 0,
112     float_tininess_before_rounding = 1
113 };
114 
115 /*
116 -------------------------------------------------------------------------------
117 Software IEC/IEEE floating-point rounding mode.
118 -------------------------------------------------------------------------------
119 */
120 extern fp_rnd float_rounding_mode;
121 enum {
122     float_round_nearest_even = FP_RN,
123     float_round_to_zero      = FP_RZ,
124     float_round_down         = FP_RM,
125     float_round_up           = FP_RP
126 };
127 
128 /*
129 -------------------------------------------------------------------------------
130 Software IEC/IEEE floating-point exception flags.
131 -------------------------------------------------------------------------------
132 */
133 extern fp_except float_exception_flags;
134 enum {
135     float_flag_inexact   =  FP_X_IMP,
136     float_flag_underflow =  FP_X_UFL,
137     float_flag_overflow  =  FP_X_OFL,
138     float_flag_divbyzero =  FP_X_DZ,
139     float_flag_invalid   = FP_X_INV
140 };
141 
142 /*
143 -------------------------------------------------------------------------------
144 Routine to raise any or all of the software IEC/IEEE floating-point
145 exception flags.
146 -------------------------------------------------------------------------------
147 */
148 void float_raise( int );
149 
150 /*
151 -------------------------------------------------------------------------------
152 Software IEC/IEEE integer-to-floating-point conversion routines.
153 -------------------------------------------------------------------------------
154 */
155 float32 int32_to_float32( int );
156 float64 int32_to_float64( int );
157 #ifdef FLOATX80
158 floatx80 int32_to_floatx80( int );
159 #endif
160 #ifdef FLOAT128
161 float128 int32_to_float128( int );
162 #endif
163 #ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */
164 float32 int64_to_float32( int64_t );
165 float64 int64_to_float64( int64_t );
166 #ifdef FLOATX80
167 floatx80 int64_to_floatx80( int64_t );
168 #endif
169 #ifdef FLOAT128
170 float128 int64_to_float128( int64_t );
171 #endif
172 #endif
173 
174 /*
175 -------------------------------------------------------------------------------
176 Software IEC/IEEE single-precision conversion routines.
177 -------------------------------------------------------------------------------
178 */
179 int float32_to_int32( float32 );
180 int float32_to_int32_round_to_zero( float32 );
181 #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */
182 int64_t float32_to_int64( float32 );
183 int64_t float32_to_int64_round_to_zero( float32 );
184 #endif
185 float64 float32_to_float64( float32 );
186 #ifdef FLOATX80
187 floatx80 float32_to_floatx80( float32 );
188 #endif
189 #ifdef FLOAT128
190 float128 float32_to_float128( float32 );
191 #endif
192 
193 /*
194 -------------------------------------------------------------------------------
195 Software IEC/IEEE single-precision operations.
196 -------------------------------------------------------------------------------
197 */
198 float32 float32_round_to_int( float32 );
199 float32 float32_add( float32, float32 );
200 float32 float32_sub( float32, float32 );
201 float32 float32_mul( float32, float32 );
202 float32 float32_div( float32, float32 );
203 float32 float32_rem( float32, float32 );
204 float32 float32_sqrt( float32 );
205 int float32_eq( float32, float32 );
206 int float32_le( float32, float32 );
207 int float32_lt( float32, float32 );
208 int float32_eq_signaling( float32, float32 );
209 int float32_le_quiet( float32, float32 );
210 int float32_lt_quiet( float32, float32 );
211 #ifndef SOFTFLOAT_FOR_GCC
212 int float32_is_signaling_nan( float32 );
213 #endif
214 
215 /*
216 -------------------------------------------------------------------------------
217 Software IEC/IEEE double-precision conversion routines.
218 -------------------------------------------------------------------------------
219 */
220 int float64_to_int32( float64 );
221 int float64_to_int32_round_to_zero( float64 );
222 #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */
223 int64_t float64_to_int64( float64 );
224 int64_t float64_to_int64_round_to_zero( float64 );
225 #endif
226 float32 float64_to_float32( float64 );
227 #ifdef FLOATX80
228 floatx80 float64_to_floatx80( float64 );
229 #endif
230 #ifdef FLOAT128
231 float128 float64_to_float128( float64 );
232 #endif
233 
234 /*
235 -------------------------------------------------------------------------------
236 Software IEC/IEEE double-precision operations.
237 -------------------------------------------------------------------------------
238 */
239 float64 float64_round_to_int( float64 );
240 float64 float64_add( float64, float64 );
241 float64 float64_sub( float64, float64 );
242 float64 float64_mul( float64, float64 );
243 float64 float64_div( float64, float64 );
244 float64 float64_rem( float64, float64 );
245 float64 float64_sqrt( float64 );
246 int float64_eq( float64, float64 );
247 int float64_le( float64, float64 );
248 int float64_lt( float64, float64 );
249 int float64_eq_signaling( float64, float64 );
250 int float64_le_quiet( float64, float64 );
251 int float64_lt_quiet( float64, float64 );
252 #ifndef SOFTFLOAT_FOR_GCC
253 int float64_is_signaling_nan( float64 );
254 #endif
255 
256 #ifdef FLOATX80
257 
258 /*
259 -------------------------------------------------------------------------------
260 Software IEC/IEEE extended double-precision conversion routines.
261 -------------------------------------------------------------------------------
262 */
263 int floatx80_to_int32( floatx80 );
264 int floatx80_to_int32_round_to_zero( floatx80 );
265 int64_t floatx80_to_int64( floatx80 );
266 int64_t floatx80_to_int64_round_to_zero( floatx80 );
267 float32 floatx80_to_float32( floatx80 );
268 float64 floatx80_to_float64( floatx80 );
269 #ifdef FLOAT128
270 float128 floatx80_to_float128( floatx80 );
271 #endif
272 
273 /*
274 -------------------------------------------------------------------------------
275 Software IEC/IEEE extended double-precision rounding precision.  Valid
276 values are 32, 64, and 80.
277 -------------------------------------------------------------------------------
278 */
279 extern int floatx80_rounding_precision;
280 
281 /*
282 -------------------------------------------------------------------------------
283 Software IEC/IEEE extended double-precision operations.
284 -------------------------------------------------------------------------------
285 */
286 floatx80 floatx80_round_to_int( floatx80 );
287 floatx80 floatx80_add( floatx80, floatx80 );
288 floatx80 floatx80_sub( floatx80, floatx80 );
289 floatx80 floatx80_mul( floatx80, floatx80 );
290 floatx80 floatx80_div( floatx80, floatx80 );
291 floatx80 floatx80_rem( floatx80, floatx80 );
292 floatx80 floatx80_sqrt( floatx80 );
293 int floatx80_eq( floatx80, floatx80 );
294 int floatx80_le( floatx80, floatx80 );
295 int floatx80_lt( floatx80, floatx80 );
296 int floatx80_eq_signaling( floatx80, floatx80 );
297 int floatx80_le_quiet( floatx80, floatx80 );
298 int floatx80_lt_quiet( floatx80, floatx80 );
299 int floatx80_is_signaling_nan( floatx80 );
300 
301 #endif
302 
303 #ifdef FLOAT128
304 
305 /*
306 -------------------------------------------------------------------------------
307 Software IEC/IEEE quadruple-precision conversion routines.
308 -------------------------------------------------------------------------------
309 */
310 int float128_to_int32( float128 );
311 int float128_to_int32_round_to_zero( float128 );
312 int64_t float128_to_int64( float128 );
313 int64_t float128_to_int64_round_to_zero( float128 );
314 float32 float128_to_float32( float128 );
315 float64 float128_to_float64( float128 );
316 #ifdef FLOATX80
317 floatx80 float128_to_floatx80( float128 );
318 #endif
319 
320 /*
321 -------------------------------------------------------------------------------
322 Software IEC/IEEE quadruple-precision operations.
323 -------------------------------------------------------------------------------
324 */
325 float128 float128_round_to_int( float128 );
326 float128 float128_add( float128, float128 );
327 float128 float128_sub( float128, float128 );
328 float128 float128_mul( float128, float128 );
329 float128 float128_div( float128, float128 );
330 float128 float128_rem( float128, float128 );
331 float128 float128_sqrt( float128 );
332 int float128_eq( float128, float128 );
333 int float128_le( float128, float128 );
334 int float128_lt( float128, float128 );
335 int float128_eq_signaling( float128, float128 );
336 int float128_le_quiet( float128, float128 );
337 int float128_lt_quiet( float128, float128 );
338 int float128_is_signaling_nan( float128 );
339 
340 #endif
341 
342