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