17804dd52SRuslan Bukin /* $NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $ */ 27804dd52SRuslan Bukin 37804dd52SRuslan Bukin /* This is a derivative work. */ 47804dd52SRuslan Bukin 57804dd52SRuslan Bukin /* 67804dd52SRuslan Bukin =============================================================================== 77804dd52SRuslan Bukin 87804dd52SRuslan Bukin This C header file is part of the SoftFloat IEC/IEEE Floating-point 97804dd52SRuslan Bukin Arithmetic Package, Release 2a. 107804dd52SRuslan Bukin 117804dd52SRuslan Bukin Written by John R. Hauser. This work was made possible in part by the 127804dd52SRuslan Bukin International Computer Science Institute, located at Suite 600, 1947 Center 137804dd52SRuslan Bukin Street, Berkeley, California 94704. Funding was partially provided by the 147804dd52SRuslan Bukin National Science Foundation under grant MIP-9311980. The original version 157804dd52SRuslan Bukin of this code was written as part of a project to build a fixed-point vector 167804dd52SRuslan Bukin processor in collaboration with the University of California at Berkeley, 177804dd52SRuslan Bukin overseen by Profs. Nelson Morgan and John Wawrzynek. More information 187804dd52SRuslan Bukin is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ 197804dd52SRuslan Bukin arithmetic/SoftFloat.html'. 207804dd52SRuslan Bukin 217804dd52SRuslan Bukin THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 227804dd52SRuslan Bukin has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 237804dd52SRuslan Bukin TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 247804dd52SRuslan Bukin PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY 257804dd52SRuslan Bukin AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. 267804dd52SRuslan Bukin 277804dd52SRuslan Bukin Derivative works are acceptable, even for commercial purposes, so long as 287804dd52SRuslan Bukin (1) they include prominent notice that the work is derivative, and (2) they 297804dd52SRuslan Bukin include prominent notice akin to these four paragraphs for those parts of 307804dd52SRuslan Bukin this code that are retained. 317804dd52SRuslan Bukin 327804dd52SRuslan Bukin =============================================================================== 337804dd52SRuslan Bukin */ 347804dd52SRuslan Bukin 357804dd52SRuslan Bukin /* 367804dd52SRuslan Bukin ------------------------------------------------------------------------------- 377804dd52SRuslan Bukin The macro `FLOATX80' must be defined to enable the extended double-precision 387804dd52SRuslan Bukin floating-point format `floatx80'. If this macro is not defined, the 397804dd52SRuslan Bukin `floatx80' type will not be defined, and none of the functions that either 407804dd52SRuslan Bukin input or output the `floatx80' type will be defined. The same applies to 417804dd52SRuslan Bukin the `FLOAT128' macro and the quadruple-precision format `float128'. 427804dd52SRuslan Bukin ------------------------------------------------------------------------------- 437804dd52SRuslan Bukin */ 447804dd52SRuslan Bukin /* #define FLOATX80 */ 457804dd52SRuslan Bukin /* #define FLOAT128 */ 467804dd52SRuslan Bukin 477804dd52SRuslan Bukin #include <fenv.h> 487804dd52SRuslan Bukin 497804dd52SRuslan Bukin /* 507804dd52SRuslan Bukin ------------------------------------------------------------------------------- 517804dd52SRuslan Bukin Software IEC/IEEE floating-point types. 527804dd52SRuslan Bukin ------------------------------------------------------------------------------- 537804dd52SRuslan Bukin */ 547804dd52SRuslan Bukin typedef unsigned int float32; 557804dd52SRuslan Bukin typedef unsigned long long float64; 567804dd52SRuslan Bukin #ifdef FLOATX80 577804dd52SRuslan Bukin typedef struct { 587804dd52SRuslan Bukin unsigned short high; 597804dd52SRuslan Bukin unsigned long long low; 607804dd52SRuslan Bukin } floatx80; 617804dd52SRuslan Bukin #endif 627804dd52SRuslan Bukin #ifdef FLOAT128 637804dd52SRuslan Bukin typedef struct { 647804dd52SRuslan Bukin unsigned long long high, low; 657804dd52SRuslan Bukin } float128; 667804dd52SRuslan Bukin #endif 677804dd52SRuslan Bukin 687804dd52SRuslan Bukin /* 697804dd52SRuslan Bukin ------------------------------------------------------------------------------- 707804dd52SRuslan Bukin Software IEC/IEEE floating-point underflow tininess-detection mode. 717804dd52SRuslan Bukin ------------------------------------------------------------------------------- 727804dd52SRuslan Bukin */ 737804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC 747804dd52SRuslan Bukin extern int float_detect_tininess; 757804dd52SRuslan Bukin #endif 767804dd52SRuslan Bukin enum { 777804dd52SRuslan Bukin float_tininess_after_rounding = 0, 787804dd52SRuslan Bukin float_tininess_before_rounding = 1 797804dd52SRuslan Bukin }; 807804dd52SRuslan Bukin 817804dd52SRuslan Bukin /* 827804dd52SRuslan Bukin ------------------------------------------------------------------------------- 837804dd52SRuslan Bukin Software IEC/IEEE floating-point rounding mode. 847804dd52SRuslan Bukin ------------------------------------------------------------------------------- 857804dd52SRuslan Bukin */ 867804dd52SRuslan Bukin extern int float_rounding_mode; 877804dd52SRuslan Bukin enum { 887804dd52SRuslan Bukin float_round_nearest_even = FE_TONEAREST, 897804dd52SRuslan Bukin float_round_to_zero = FE_TOWARDZERO, 907804dd52SRuslan Bukin float_round_down = FE_DOWNWARD, 917804dd52SRuslan Bukin float_round_up = FE_UPWARD 927804dd52SRuslan Bukin }; 937804dd52SRuslan Bukin 947804dd52SRuslan Bukin /* 957804dd52SRuslan Bukin ------------------------------------------------------------------------------- 967804dd52SRuslan Bukin Software IEC/IEEE floating-point exception flags. 977804dd52SRuslan Bukin ------------------------------------------------------------------------------- 987804dd52SRuslan Bukin */ 997804dd52SRuslan Bukin extern int float_exception_flags; 1007804dd52SRuslan Bukin extern int float_exception_mask; 1017804dd52SRuslan Bukin enum { 1027804dd52SRuslan Bukin float_flag_inexact = FE_INEXACT, 1037804dd52SRuslan Bukin float_flag_underflow = FE_UNDERFLOW, 1047804dd52SRuslan Bukin float_flag_overflow = FE_OVERFLOW, 1057804dd52SRuslan Bukin float_flag_divbyzero = FE_DIVBYZERO, 1067804dd52SRuslan Bukin float_flag_invalid = FE_INVALID 1077804dd52SRuslan Bukin }; 1087804dd52SRuslan Bukin 1097804dd52SRuslan Bukin /* 1107804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1117804dd52SRuslan Bukin Routine to raise any or all of the software IEC/IEEE floating-point 1127804dd52SRuslan Bukin exception flags. 1137804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1147804dd52SRuslan Bukin */ 1157804dd52SRuslan Bukin void float_raise( int ); 1167804dd52SRuslan Bukin 1177804dd52SRuslan Bukin /* 1187804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1197804dd52SRuslan Bukin Software IEC/IEEE integer-to-floating-point conversion routines. 1207804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1217804dd52SRuslan Bukin */ 1227804dd52SRuslan Bukin float32 int32_to_float32( int ); 1237804dd52SRuslan Bukin float64 int32_to_float64( int ); 1247804dd52SRuslan Bukin #ifdef FLOATX80 1257804dd52SRuslan Bukin floatx80 int32_to_floatx80( int ); 1267804dd52SRuslan Bukin #endif 1277804dd52SRuslan Bukin #ifdef FLOAT128 1287804dd52SRuslan Bukin float128 int32_to_float128( int ); 1297804dd52SRuslan Bukin #endif 1307804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */ 1317804dd52SRuslan Bukin float32 int64_to_float32( long long ); 1327804dd52SRuslan Bukin float64 int64_to_float64( long long ); 1337804dd52SRuslan Bukin #ifdef FLOATX80 1347804dd52SRuslan Bukin floatx80 int64_to_floatx80( long long ); 1357804dd52SRuslan Bukin #endif 1367804dd52SRuslan Bukin #ifdef FLOAT128 1377804dd52SRuslan Bukin float128 int64_to_float128( long long ); 1387804dd52SRuslan Bukin #endif 1397804dd52SRuslan Bukin #endif 1407804dd52SRuslan Bukin 1417804dd52SRuslan Bukin /* 1427804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1437804dd52SRuslan Bukin Software IEC/IEEE single-precision conversion routines. 1447804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1457804dd52SRuslan Bukin */ 1467804dd52SRuslan Bukin int float32_to_int32( float32 ); 1477804dd52SRuslan Bukin int float32_to_int32_round_to_zero( float32 ); 1487804dd52SRuslan Bukin #if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS) 1497804dd52SRuslan Bukin unsigned int float32_to_uint32_round_to_zero( float32 ); 1507804dd52SRuslan Bukin #endif 1517804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ 1527804dd52SRuslan Bukin long long float32_to_int64( float32 ); 1537804dd52SRuslan Bukin long long float32_to_int64_round_to_zero( float32 ); 1547804dd52SRuslan Bukin #endif 1557804dd52SRuslan Bukin float64 float32_to_float64( float32 ); 1567804dd52SRuslan Bukin #ifdef FLOATX80 1577804dd52SRuslan Bukin floatx80 float32_to_floatx80( float32 ); 1587804dd52SRuslan Bukin #endif 1597804dd52SRuslan Bukin #ifdef FLOAT128 1607804dd52SRuslan Bukin float128 float32_to_float128( float32 ); 1617804dd52SRuslan Bukin #endif 1627804dd52SRuslan Bukin 1637804dd52SRuslan Bukin /* 1647804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1657804dd52SRuslan Bukin Software IEC/IEEE single-precision operations. 1667804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1677804dd52SRuslan Bukin */ 1687804dd52SRuslan Bukin float32 float32_round_to_int( float32 ); 1697804dd52SRuslan Bukin float32 float32_add( float32, float32 ); 1707804dd52SRuslan Bukin float32 float32_sub( float32, float32 ); 1717804dd52SRuslan Bukin float32 float32_mul( float32, float32 ); 1727804dd52SRuslan Bukin float32 float32_div( float32, float32 ); 1737804dd52SRuslan Bukin float32 float32_rem( float32, float32 ); 1747804dd52SRuslan Bukin float32 float32_sqrt( float32 ); 1757804dd52SRuslan Bukin int float32_eq( float32, float32 ); 1767804dd52SRuslan Bukin int float32_le( float32, float32 ); 1777804dd52SRuslan Bukin int float32_lt( float32, float32 ); 1787804dd52SRuslan Bukin int float32_eq_signaling( float32, float32 ); 1797804dd52SRuslan Bukin int float32_le_quiet( float32, float32 ); 1807804dd52SRuslan Bukin int float32_lt_quiet( float32, float32 ); 1817804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC 1827804dd52SRuslan Bukin int float32_is_signaling_nan( float32 ); 1837804dd52SRuslan Bukin #endif 1847804dd52SRuslan Bukin 1857804dd52SRuslan Bukin /* 1867804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1877804dd52SRuslan Bukin Software IEC/IEEE double-precision conversion routines. 1887804dd52SRuslan Bukin ------------------------------------------------------------------------------- 1897804dd52SRuslan Bukin */ 1907804dd52SRuslan Bukin int float64_to_int32( float64 ); 1917804dd52SRuslan Bukin int float64_to_int32_round_to_zero( float64 ); 1927804dd52SRuslan Bukin #if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS) 1937804dd52SRuslan Bukin unsigned int float64_to_uint32_round_to_zero( float64 ); 1947804dd52SRuslan Bukin #endif 1957804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ 1967804dd52SRuslan Bukin long long float64_to_int64( float64 ); 1977804dd52SRuslan Bukin long long float64_to_int64_round_to_zero( float64 ); 1987804dd52SRuslan Bukin #endif 1997804dd52SRuslan Bukin float32 float64_to_float32( float64 ); 2007804dd52SRuslan Bukin #ifdef FLOATX80 2017804dd52SRuslan Bukin floatx80 float64_to_floatx80( float64 ); 2027804dd52SRuslan Bukin #endif 2037804dd52SRuslan Bukin #ifdef FLOAT128 2047804dd52SRuslan Bukin float128 float64_to_float128( float64 ); 2057804dd52SRuslan Bukin #endif 2067804dd52SRuslan Bukin 2077804dd52SRuslan Bukin /* 2087804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2097804dd52SRuslan Bukin Software IEC/IEEE double-precision operations. 2107804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2117804dd52SRuslan Bukin */ 2127804dd52SRuslan Bukin float64 float64_round_to_int( float64 ); 2137804dd52SRuslan Bukin float64 float64_add( float64, float64 ); 2147804dd52SRuslan Bukin float64 float64_sub( float64, float64 ); 2157804dd52SRuslan Bukin float64 float64_mul( float64, float64 ); 2167804dd52SRuslan Bukin float64 float64_div( float64, float64 ); 2177804dd52SRuslan Bukin float64 float64_rem( float64, float64 ); 2187804dd52SRuslan Bukin float64 float64_sqrt( float64 ); 2197804dd52SRuslan Bukin int float64_eq( float64, float64 ); 2207804dd52SRuslan Bukin int float64_le( float64, float64 ); 2217804dd52SRuslan Bukin int float64_lt( float64, float64 ); 2227804dd52SRuslan Bukin int float64_eq_signaling( float64, float64 ); 2237804dd52SRuslan Bukin int float64_le_quiet( float64, float64 ); 2247804dd52SRuslan Bukin int float64_lt_quiet( float64, float64 ); 2257804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC 2267804dd52SRuslan Bukin int float64_is_signaling_nan( float64 ); 2277804dd52SRuslan Bukin #endif 2287804dd52SRuslan Bukin 2297804dd52SRuslan Bukin #ifdef FLOATX80 2307804dd52SRuslan Bukin 2317804dd52SRuslan Bukin /* 2327804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2337804dd52SRuslan Bukin Software IEC/IEEE extended double-precision conversion routines. 2347804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2357804dd52SRuslan Bukin */ 2367804dd52SRuslan Bukin int floatx80_to_int32( floatx80 ); 2377804dd52SRuslan Bukin int floatx80_to_int32_round_to_zero( floatx80 ); 2387804dd52SRuslan Bukin long long floatx80_to_int64( floatx80 ); 2397804dd52SRuslan Bukin long long floatx80_to_int64_round_to_zero( floatx80 ); 2407804dd52SRuslan Bukin float32 floatx80_to_float32( floatx80 ); 2417804dd52SRuslan Bukin float64 floatx80_to_float64( floatx80 ); 2427804dd52SRuslan Bukin #ifdef FLOAT128 2437804dd52SRuslan Bukin float128 floatx80_to_float128( floatx80 ); 2447804dd52SRuslan Bukin #endif 2457804dd52SRuslan Bukin 2467804dd52SRuslan Bukin /* 2477804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2487804dd52SRuslan Bukin Software IEC/IEEE extended double-precision rounding precision. Valid 2497804dd52SRuslan Bukin values are 32, 64, and 80. 2507804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2517804dd52SRuslan Bukin */ 2527804dd52SRuslan Bukin extern int floatx80_rounding_precision; 2537804dd52SRuslan Bukin 2547804dd52SRuslan Bukin /* 2557804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2567804dd52SRuslan Bukin Software IEC/IEEE extended double-precision operations. 2577804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2587804dd52SRuslan Bukin */ 2597804dd52SRuslan Bukin floatx80 floatx80_round_to_int( floatx80 ); 2607804dd52SRuslan Bukin floatx80 floatx80_add( floatx80, floatx80 ); 2617804dd52SRuslan Bukin floatx80 floatx80_sub( floatx80, floatx80 ); 2627804dd52SRuslan Bukin floatx80 floatx80_mul( floatx80, floatx80 ); 2637804dd52SRuslan Bukin floatx80 floatx80_div( floatx80, floatx80 ); 2647804dd52SRuslan Bukin floatx80 floatx80_rem( floatx80, floatx80 ); 2657804dd52SRuslan Bukin floatx80 floatx80_sqrt( floatx80 ); 2667804dd52SRuslan Bukin int floatx80_eq( floatx80, floatx80 ); 2677804dd52SRuslan Bukin int floatx80_le( floatx80, floatx80 ); 2687804dd52SRuslan Bukin int floatx80_lt( floatx80, floatx80 ); 2697804dd52SRuslan Bukin int floatx80_eq_signaling( floatx80, floatx80 ); 2707804dd52SRuslan Bukin int floatx80_le_quiet( floatx80, floatx80 ); 2717804dd52SRuslan Bukin int floatx80_lt_quiet( floatx80, floatx80 ); 2727804dd52SRuslan Bukin int floatx80_is_signaling_nan( floatx80 ); 2737804dd52SRuslan Bukin 2747804dd52SRuslan Bukin #endif 2757804dd52SRuslan Bukin 2767804dd52SRuslan Bukin #ifdef FLOAT128 2777804dd52SRuslan Bukin 2787804dd52SRuslan Bukin /* 2797804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2807804dd52SRuslan Bukin Software IEC/IEEE quadruple-precision conversion routines. 2817804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2827804dd52SRuslan Bukin */ 2837804dd52SRuslan Bukin int float128_to_int32( float128 ); 2847804dd52SRuslan Bukin int float128_to_int32_round_to_zero( float128 ); 2857804dd52SRuslan Bukin long long float128_to_int64( float128 ); 2867804dd52SRuslan Bukin long long float128_to_int64_round_to_zero( float128 ); 2877804dd52SRuslan Bukin float32 float128_to_float32( float128 ); 2887804dd52SRuslan Bukin float64 float128_to_float64( float128 ); 2897804dd52SRuslan Bukin #ifdef FLOATX80 2907804dd52SRuslan Bukin floatx80 float128_to_floatx80( float128 ); 2917804dd52SRuslan Bukin #endif 2927804dd52SRuslan Bukin 2937804dd52SRuslan Bukin /* 2947804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2957804dd52SRuslan Bukin Software IEC/IEEE quadruple-precision operations. 2967804dd52SRuslan Bukin ------------------------------------------------------------------------------- 2977804dd52SRuslan Bukin */ 2987804dd52SRuslan Bukin float128 float128_round_to_int( float128 ); 2997804dd52SRuslan Bukin float128 float128_add( float128, float128 ); 3007804dd52SRuslan Bukin float128 float128_sub( float128, float128 ); 3017804dd52SRuslan Bukin float128 float128_mul( float128, float128 ); 3027804dd52SRuslan Bukin float128 float128_div( float128, float128 ); 3037804dd52SRuslan Bukin float128 float128_rem( float128, float128 ); 3047804dd52SRuslan Bukin float128 float128_sqrt( float128 ); 3057804dd52SRuslan Bukin int float128_eq( float128, float128 ); 3067804dd52SRuslan Bukin int float128_le( float128, float128 ); 3077804dd52SRuslan Bukin int float128_lt( float128, float128 ); 3087804dd52SRuslan Bukin int float128_eq_signaling( float128, float128 ); 3097804dd52SRuslan Bukin int float128_le_quiet( float128, float128 ); 3107804dd52SRuslan Bukin int float128_lt_quiet( float128, float128 ); 3117804dd52SRuslan Bukin int float128_is_signaling_nan( float128 ); 3127804dd52SRuslan Bukin 3137804dd52SRuslan Bukin #endif 3147804dd52SRuslan Bukin 315