7 * The code in this source file is derived from release 2a of the SoftFloat
8 * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
9 * some later contributions) are provided under that license, as detailed below.
10 * It has subsequently been modified by contributors to the QEMU Project,
11 * so some portions are provided under:
12 * the SoftFloat-2a license
16 * Any future contributions to this file after December 1st 2014 will be
17 * taken to be licensed under the Softfloat-2a license unless specifically
18 * indicated otherwise.
22 ===============================================================================
23 This C header file is part of the SoftFloat IEC/IEEE Floating-point
24 Arithmetic Package, Release 2a.
26 Written by John R. Hauser. This work was made possible in part by the
27 International Computer Science Institute, located at Suite 600, 1947 Center
28 Street, Berkeley, California 94704. Funding was partially provided by the
29 National Science Foundation under grant MIP-9311980. The original version
30 of this code was written as part of a project to build a fixed-point vector
31 processor in collaboration with the University of California at Berkeley,
32 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
33 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
34 arithmetic/SoftFloat.html'.
36 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
37 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
38 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
39 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
40 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
42 Derivative works are acceptable, even for commercial purposes, so long as
43 (1) they include prominent notice that the work is derivative, and (2) they
44 include prominent notice akin to these four paragraphs for those parts of
45 this code that are retained.
47 ===============================================================================
51 * Copyright (c) 2006, Fabrice Bellard
52 * All rights reserved.
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions are met:
57 * 1. Redistributions of source code must retain the above copyright notice,
58 * this list of conditions and the following disclaimer.
60 * 2. Redistributions in binary form must reproduce the above copyright notice,
61 * this list of conditions and the following disclaimer in the documentation
62 * and/or other materials provided with the distribution.
64 * 3. Neither the name of the copyright holder nor the names of its contributors
65 * may be used to endorse or promote products derived from this software without
66 * specific prior written permission.
68 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
69 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
70 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
71 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
72 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
73 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
74 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
75 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
76 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
77 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
78 * THE POSSIBILITY OF SUCH DAMAGE.
81 /* Portions of this work are licensed under the terms of the GNU GPL,
82 * version 2 or later. See the COPYING file in the top-level directory.
88 #if defined(CONFIG_SOLARIS) && defined(CONFIG_NEEDS_LIBSUNMATH)
93 /* This 'flag' type must be able to hold at least 0 and 1. It should
94 * probably be replaced with 'bool' but the uses would need to be audited
95 * to check that they weren't accidentally relying on it being a larger type.
98 typedef uint64_t flag;
101 #define LIT64( a ) a##ULL
103 /*----------------------------------------------------------------------------
104 | Software IEC/IEEE floating-point ordering relations
105 *----------------------------------------------------------------------------*/
107 float_relation_less = -1,
108 float_relation_equal = 0,
109 float_relation_greater = 1,
110 float_relation_unordered = 2
113 /*----------------------------------------------------------------------------
114 | Software IEC/IEEE floating-point types.
115 *----------------------------------------------------------------------------*/
116 /* Use structures for soft-float types. This prevents accidentally mixing
117 them with native int/float types. A sufficiently clever compiler and
118 sane ABI should be able to see though these structs. However
119 x86/gcc 3.x seems to struggle a bit, so leave them disabled by default. */
120 //#define USE_SOFTFLOAT_STRUCT_TYPES
121 #ifdef USE_SOFTFLOAT_STRUCT_TYPES
125 #define float16_val(x) (((float16)(x)).v)
126 #define make_float16(x) __extension__ ({ float16 f16_val = {x}; f16_val; })
127 #define const_float16(x) { x }
131 /* The cast ensures an error if the wrong type is passed. */
132 #define float32_val(x) (((float32)(x)).v)
133 #define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; })
134 #define const_float32(x) { x }
138 #define float64_val(x) (((float64)(x)).v)
139 #define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; })
140 #define const_float64(x) { x }
142 typedef uint16_t float16;
143 typedef uint32_t float32;
144 typedef uint64_t float64;
145 #define float16_val(x) (x)
146 #define float32_val(x) (x)
147 #define float64_val(x) (x)
148 #define make_float16(x) (x)
149 #define make_float32(x) (x)
150 #define make_float64(x) (x)
151 #define const_float16(x) (x)
152 #define const_float32(x) (x)
153 #define const_float64(x) (x)
160 #ifdef HOST_WORDS_BIGENDIAN
167 /*----------------------------------------------------------------------------
168 | Software IEC/IEEE floating-point underflow tininess-detection mode.
169 *----------------------------------------------------------------------------*/
171 float_tininess_after_rounding = 0,
172 float_tininess_before_rounding = 1
175 /*----------------------------------------------------------------------------
176 | Software IEC/IEEE floating-point rounding mode.
177 *----------------------------------------------------------------------------*/
179 float_round_nearest_even = 0,
180 float_round_down = 1,
182 float_round_to_zero = 3,
183 float_round_ties_away = 4,
186 /*----------------------------------------------------------------------------
187 | Software IEC/IEEE floating-point exception flags.
188 *----------------------------------------------------------------------------*/
190 float_flag_invalid = 0x01,
191 float_flag_denormal = 0x02,
192 float_flag_divbyzero = 0x04,
193 float_flag_overflow = 0x08,
194 float_flag_underflow = 0x10,
195 float_flag_inexact = 0x20,
196 float_flag_signaling = 0x40,
197 float_flag_decimal = 0x80
200 /*----------------------------------------------------------------------------
201 | Variables for storing sign, exponent and significand of overflowed or
202 | underflowed extended double-precision floating-point value.
203 | Variables for storing sign, exponent and significand of internal extended
204 | double-precision floating-point value for external use.
205 *----------------------------------------------------------------------------*/
207 extern flag floatx80_internal_sign;
208 extern int32_t floatx80_internal_exp;
209 extern uint64_t floatx80_internal_sig;
210 extern int32_t floatx80_internal_exp0;
211 extern uint64_t floatx80_internal_sig0;
212 extern uint64_t floatx80_internal_sig1;
213 extern int8_t floatx80_internal_precision;
214 extern int8_t floatx80_internal_mode;
216 typedef struct float_status {
217 signed char float_detect_tininess;
218 signed char float_rounding_mode;
219 uint8_t float_exception_flags;
220 signed char floatx80_rounding_precision;
221 /* should denormalised results go to zero and set the inexact flag? */
223 /* should denormalised inputs go to zero and set the input_denormal flag? */
224 flag flush_inputs_to_zero;
225 flag default_nan_mode;
226 flag snan_bit_is_one;
227 flag floatx80_special_flags;
230 /*----------------------------------------------------------------------------
231 | Function for getting sign, exponent and significand of extended
232 | double-precision floating-point intermediate result for external use.
233 *----------------------------------------------------------------------------*/
234 floatx80 getFloatInternalOverflow( void );
235 floatx80 getFloatInternalUnderflow( void );
236 floatx80 getFloatInternalRoundedAll( void );
237 floatx80 getFloatInternalRoundedSome( void );
238 floatx80 getFloatInternalUnrounded( void );
239 floatx80 getFloatInternalFloatx80( void );
240 uint64_t getFloatInternalGRS( void );
242 static inline void set_float_detect_tininess(int val, float_status *status)
244 status->float_detect_tininess = val;
246 static inline void set_float_rounding_mode(int val, float_status *status)
248 status->float_rounding_mode = val;
250 static inline void set_float_exception_flags(int val, float_status *status)
252 status->float_exception_flags = val;
254 static inline void set_floatx80_rounding_precision(int val,
255 float_status *status)
257 status->floatx80_rounding_precision = val;
259 static inline void set_flush_to_zero(flag val, float_status *status)
261 status->flush_to_zero = val;
263 static inline void set_flush_inputs_to_zero(flag val, float_status *status)
265 status->flush_inputs_to_zero = val;
267 static inline void set_default_nan_mode(flag val, float_status *status)
269 status->default_nan_mode = val;
271 static inline void set_snan_bit_is_one(flag val, float_status *status)
273 status->snan_bit_is_one = val;
275 static inline int get_float_detect_tininess(float_status *status)
277 return status->float_detect_tininess;
279 static inline int get_float_rounding_mode(float_status *status)
281 return status->float_rounding_mode;
283 static inline int get_float_exception_flags(float_status *status)
285 return status->float_exception_flags;
287 static inline int get_floatx80_rounding_precision(float_status *status)
289 return status->floatx80_rounding_precision;
291 static inline flag get_flush_to_zero(float_status *status)
293 return status->flush_to_zero;
295 static inline flag get_flush_inputs_to_zero(float_status *status)
297 return status->flush_inputs_to_zero;
299 static inline flag get_default_nan_mode(float_status *status)
301 return status->default_nan_mode;
304 /*----------------------------------------------------------------------------
305 | Special flags for indicating some unique behavior is required.
306 *----------------------------------------------------------------------------*/
308 cmp_signed_nan = 0x01, addsub_swap_inf = 0x02, infinity_clear_intbit = 0x04
311 static inline void set_special_flags(uint8_t flags, float_status *status)
313 status->floatx80_special_flags = flags;
315 static inline int8_t fcmp_signed_nan(float_status *status)
317 return status->floatx80_special_flags & cmp_signed_nan;
319 static inline int8_t faddsub_swap_inf(float_status *status)
321 return status->floatx80_special_flags & addsub_swap_inf;
323 static inline int8_t inf_clear_intbit(float_status *status)
325 return status->floatx80_special_flags & infinity_clear_intbit;
328 /*----------------------------------------------------------------------------
329 | Routine to raise any or all of the software IEC/IEEE floating-point
331 *----------------------------------------------------------------------------*/
332 void float_raise(uint8_t flags, float_status *status);
335 /*----------------------------------------------------------------------------
336 | The pattern for a default generated single-precision NaN.
337 *----------------------------------------------------------------------------*/
338 #define float32_default_nan 0x7FFFFFFF
340 /*----------------------------------------------------------------------------
341 | The pattern for a default generated double-precision NaN.
342 *----------------------------------------------------------------------------*/
343 #define float64_default_nan LIT64( 0x7FFFFFFFFFFFFFFF )
345 /*----------------------------------------------------------------------------
346 | The pattern for a default generated extended double-precision NaN. The
347 | `high' and `low' values hold the most- and least-significant bits,
349 *----------------------------------------------------------------------------*/
350 #define floatx80_default_nan_high 0x7FFF
351 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
353 /*----------------------------------------------------------------------------
354 | The pattern for a default generated extended double-precision infinity.
355 *----------------------------------------------------------------------------*/
356 #define floatx80_default_infinity_low LIT64( 0x0000000000000000 )
358 /*----------------------------------------------------------------------------
359 | If `a' is denormal and we are in flush-to-zero mode then set the
360 | input-denormal exception and return zero. Otherwise just return the value.
361 *----------------------------------------------------------------------------*/
362 float64 float64_squash_input_denormal(float64 a, float_status *status);
364 /*----------------------------------------------------------------------------
365 | Options to indicate which negations to perform in float*_muladd()
366 | Using these differs from negating an input or output before calling
367 | the muladd function in that this means that a NaN doesn't have its
368 | sign bit inverted before it is propagated.
369 | We also support halving the result before rounding, as a special
370 | case to support the ARM fused-sqrt-step instruction FRSQRTS.
371 *----------------------------------------------------------------------------*/
373 float_muladd_negate_c = 1,
374 float_muladd_negate_product = 2,
375 float_muladd_negate_result = 4,
376 float_muladd_halve_result = 8,
379 /*----------------------------------------------------------------------------
380 | Software IEC/IEEE integer-to-floating-point conversion routines.
381 *----------------------------------------------------------------------------*/
383 floatx80 int32_to_floatx80(int32_t);
384 floatx80 int64_to_floatx80(int64_t);
386 /*----------------------------------------------------------------------------
387 | Software IEC/IEEE single-precision conversion routines.
388 *----------------------------------------------------------------------------*/
389 floatx80 float32_to_floatx80(float32, float_status *status);
390 floatx80 float32_to_floatx80_allowunnormal(float32, float_status *status);
392 /*----------------------------------------------------------------------------
393 | Software IEC/IEEE double-precision conversion routines.
394 *----------------------------------------------------------------------------*/
395 floatx80 float64_to_floatx80(float64, float_status *status);
397 floatx80 float64_to_floatx80_allowunnormal( float64 a, float_status *status );
399 /*----------------------------------------------------------------------------
400 | Software IEC/IEEE extended double-precision conversion routines.
401 *----------------------------------------------------------------------------*/
402 int32_t floatx80_to_int32(floatx80, float_status *status);
404 int16_t floatx80_to_int16(floatx80, float_status *status);
405 int8_t floatx80_to_int8(floatx80, float_status *status);
407 int32_t floatx80_to_int32_round_to_zero(floatx80, float_status *status);
408 int64_t floatx80_to_int64(floatx80, float_status *status);
409 float32 floatx80_to_float32(floatx80, float_status *status);
410 float64 floatx80_to_float64(floatx80, float_status *status);
412 floatx80 floatx80_to_floatx80( floatx80, float_status *status);
413 floatx80 floatdecimal_to_floatx80(floatx80, float_status *status);
414 floatx80 floatx80_to_floatdecimal(floatx80, int32_t*, float_status *status);
417 uint64_t extractFloatx80Frac( floatx80 a );
418 int32_t extractFloatx80Exp( floatx80 a );
419 flag extractFloatx80Sign( floatx80 a );
421 floatx80 floatx80_round_to_int_toward_zero( floatx80 a, float_status *status);
422 floatx80 floatx80_round_to_float32( floatx80, float_status *status );
423 floatx80 floatx80_round_to_float64( floatx80, float_status *status );
424 floatx80 floatx80_round32( floatx80, float_status *status);
425 floatx80 floatx80_round64( floatx80, float_status *status);
427 flag floatx80_eq( floatx80, floatx80, float_status *status);
428 flag floatx80_le( floatx80, floatx80, float_status *status);
429 flag floatx80_lt( floatx80, floatx80, float_status *status);
432 // functions are in softfloat.c
433 floatx80 floatx80_move( floatx80 a, float_status *status );
434 floatx80 floatx80_abs( floatx80 a, float_status *status );
435 floatx80 floatx80_neg( floatx80 a, float_status *status );
436 floatx80 floatx80_getexp( floatx80 a, float_status *status );
437 floatx80 floatx80_getman( floatx80 a, float_status *status );
438 floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status );
439 floatx80 floatx80_rem( floatx80 a, floatx80 b, uint64_t *q, flag *s, float_status *status );
440 floatx80 floatx80_mod( floatx80 a, floatx80 b, uint64_t *q, flag *s, float_status *status );
441 floatx80 floatx80_sglmul( floatx80 a, floatx80 b, float_status *status );
442 floatx80 floatx80_sgldiv( floatx80 a, floatx80 b, float_status *status );
443 floatx80 floatx80_cmp( floatx80 a, floatx80 b, float_status *status );
444 floatx80 floatx80_tst( floatx80 a, float_status *status );
446 // functions are in softfloat_fpsp.c
447 floatx80 floatx80_acos(floatx80 a, float_status *status);
448 floatx80 floatx80_asin(floatx80 a, float_status *status);
449 floatx80 floatx80_atan(floatx80 a, float_status *status);
450 floatx80 floatx80_atanh(floatx80 a, float_status *status);
451 floatx80 floatx80_cos(floatx80 a, float_status *status);
452 floatx80 floatx80_cosh(floatx80 a, float_status *status);
453 floatx80 floatx80_etox(floatx80 a, float_status *status);
454 floatx80 floatx80_etoxm1(floatx80 a, float_status *status);
455 floatx80 floatx80_log10(floatx80 a, float_status *status);
456 floatx80 floatx80_log2(floatx80 a, float_status *status);
457 floatx80 floatx80_logn(floatx80 a, float_status *status);
458 floatx80 floatx80_lognp1(floatx80 a, float_status *status);
459 floatx80 floatx80_sin(floatx80 a, float_status *status);
460 floatx80 floatx80_sinh(floatx80 a, float_status *status);
461 floatx80 floatx80_tan(floatx80 a, float_status *status);
462 floatx80 floatx80_tanh(floatx80 a, float_status *status);
463 floatx80 floatx80_tentox(floatx80 a, float_status *status);
464 floatx80 floatx80_twotox(floatx80 a, float_status *status);
467 // functions originally internal to softfloat.c
468 void normalizeFloatx80Subnormal( uint64_t aSig, int32_t *zExpPtr, uint64_t *zSigPtr );
469 floatx80 packFloatx80( flag zSign, int32_t zExp, uint64_t zSig );
470 floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status);
472 /*----------------------------------------------------------------------------
473 | Software IEC/IEEE extended double-precision operations.
474 *----------------------------------------------------------------------------*/
475 floatx80 floatx80_round_to_int(floatx80, float_status *status);
476 floatx80 floatx80_add(floatx80, floatx80, float_status *status);
477 floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
478 floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
479 floatx80 floatx80_div(floatx80, floatx80, float_status *status);
480 floatx80 floatx80_sqrt(floatx80, float_status *status);
481 floatx80 floatx80_normalize(floatx80);
482 floatx80 floatx80_denormalize(floatx80, flag);
484 static inline int floatx80_is_zero_or_denormal(floatx80 a)
486 return (a.high & 0x7fff) == 0;
489 static inline int floatx80_is_any_nan(floatx80 a)
491 return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
494 /*----------------------------------------------------------------------------
495 | Return whether the given value is an invalid floatx80 encoding.
496 | Invalid floatx80 encodings arise when the integer bit is not set, but
497 | the exponent is not zero. The only times the integer bit is permitted to
498 | be zero is in subnormal numbers and the value zero.
499 | This includes what the Intel software developer's manual calls pseudo-NaNs,
500 | pseudo-infinities and un-normal numbers. It does not include
501 | pseudo-denormals, which must still be correctly handled as inputs even
502 | if they are never generated as outputs.
503 *----------------------------------------------------------------------------*/
504 static inline bool floatx80_invalid_encoding(floatx80 a)
506 return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0 && (a.high & 0x7FFF) != 0x7FFF;
509 #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
510 #define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
511 #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
512 #define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
513 #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
514 #define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
516 #endif /* SOFTFLOAT_H */