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