14ce26106SWarner Losh /*	$NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $	*/
24ce26106SWarner Losh /* $FreeBSD$ */
34ce26106SWarner Losh 
44ce26106SWarner Losh /* This is a derivative work. */
54ce26106SWarner Losh 
64ce26106SWarner Losh /*
74ce26106SWarner Losh ===============================================================================
84ce26106SWarner Losh 
94ce26106SWarner Losh This C header file is part of the SoftFloat IEC/IEEE Floating-point
104ce26106SWarner Losh Arithmetic Package, Release 2a.
114ce26106SWarner Losh 
124ce26106SWarner Losh Written by John R. Hauser.  This work was made possible in part by the
134ce26106SWarner Losh International Computer Science Institute, located at Suite 600, 1947 Center
144ce26106SWarner Losh Street, Berkeley, California 94704.  Funding was partially provided by the
154ce26106SWarner Losh National Science Foundation under grant MIP-9311980.  The original version
164ce26106SWarner Losh of this code was written as part of a project to build a fixed-point vector
174ce26106SWarner Losh processor in collaboration with the University of California at Berkeley,
184ce26106SWarner Losh overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
194ce26106SWarner Losh is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
204ce26106SWarner Losh arithmetic/SoftFloat.html'.
214ce26106SWarner Losh 
224ce26106SWarner Losh THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
234ce26106SWarner Losh has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
244ce26106SWarner Losh TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
254ce26106SWarner Losh PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
264ce26106SWarner Losh AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
274ce26106SWarner Losh 
284ce26106SWarner Losh Derivative works are acceptable, even for commercial purposes, so long as
294ce26106SWarner Losh (1) they include prominent notice that the work is derivative, and (2) they
304ce26106SWarner Losh include prominent notice akin to these four paragraphs for those parts of
314ce26106SWarner Losh this code that are retained.
324ce26106SWarner Losh 
334ce26106SWarner Losh ===============================================================================
344ce26106SWarner Losh */
354ce26106SWarner Losh 
364ce26106SWarner Losh /*
374ce26106SWarner Losh -------------------------------------------------------------------------------
384ce26106SWarner Losh The macro `FLOATX80' must be defined to enable the extended double-precision
394ce26106SWarner Losh floating-point format `floatx80'.  If this macro is not defined, the
404ce26106SWarner Losh `floatx80' type will not be defined, and none of the functions that either
414ce26106SWarner Losh input or output the `floatx80' type will be defined.  The same applies to
424ce26106SWarner Losh the `FLOAT128' macro and the quadruple-precision format `float128'.
434ce26106SWarner Losh -------------------------------------------------------------------------------
444ce26106SWarner Losh */
454ce26106SWarner Losh /* #define FLOATX80 */
464ce26106SWarner Losh /* #define FLOAT128 */
474ce26106SWarner Losh 
48*b1d04644SDavid Schultz #include <fenv.h>
494ce26106SWarner Losh 
504ce26106SWarner Losh /*
514ce26106SWarner Losh -------------------------------------------------------------------------------
524ce26106SWarner Losh Software IEC/IEEE floating-point types.
534ce26106SWarner Losh -------------------------------------------------------------------------------
544ce26106SWarner Losh */
554ce26106SWarner Losh typedef unsigned int float32;
564ce26106SWarner Losh typedef unsigned long long float64;
574ce26106SWarner Losh #ifdef FLOATX80
584ce26106SWarner Losh typedef struct {
594ce26106SWarner Losh     unsigned short high;
604ce26106SWarner Losh     unsigned long long low;
614ce26106SWarner Losh } floatx80;
624ce26106SWarner Losh #endif
634ce26106SWarner Losh #ifdef FLOAT128
644ce26106SWarner Losh typedef struct {
654ce26106SWarner Losh     unsigned long long high, low;
664ce26106SWarner Losh } float128;
674ce26106SWarner Losh #endif
684ce26106SWarner Losh 
694ce26106SWarner Losh /*
704ce26106SWarner Losh -------------------------------------------------------------------------------
714ce26106SWarner Losh Software IEC/IEEE floating-point underflow tininess-detection mode.
724ce26106SWarner Losh -------------------------------------------------------------------------------
734ce26106SWarner Losh */
744ce26106SWarner Losh #ifndef SOFTFLOAT_FOR_GCC
754ce26106SWarner Losh extern int float_detect_tininess;
764ce26106SWarner Losh #endif
774ce26106SWarner Losh enum {
784ce26106SWarner Losh     float_tininess_after_rounding  = 0,
794ce26106SWarner Losh     float_tininess_before_rounding = 1
804ce26106SWarner Losh };
814ce26106SWarner Losh 
824ce26106SWarner Losh /*
834ce26106SWarner Losh -------------------------------------------------------------------------------
844ce26106SWarner Losh Software IEC/IEEE floating-point rounding mode.
854ce26106SWarner Losh -------------------------------------------------------------------------------
864ce26106SWarner Losh */
87*b1d04644SDavid Schultz extern int float_rounding_mode;
884ce26106SWarner Losh enum {
89*b1d04644SDavid Schultz     float_round_nearest_even = FE_TONEAREST,
90*b1d04644SDavid Schultz     float_round_to_zero      = FE_TOWARDZERO,
91*b1d04644SDavid Schultz     float_round_down         = FE_DOWNWARD,
92*b1d04644SDavid Schultz     float_round_up           = FE_UPWARD
934ce26106SWarner Losh };
944ce26106SWarner Losh 
954ce26106SWarner Losh /*
964ce26106SWarner Losh -------------------------------------------------------------------------------
974ce26106SWarner Losh Software IEC/IEEE floating-point exception flags.
984ce26106SWarner Losh -------------------------------------------------------------------------------
994ce26106SWarner Losh */
100*b1d04644SDavid Schultz extern int float_exception_flags;
101*b1d04644SDavid Schultz extern int float_exception_mask;
1024ce26106SWarner Losh enum {
103*b1d04644SDavid Schultz     float_flag_inexact   = FE_INEXACT,
104*b1d04644SDavid Schultz     float_flag_underflow = FE_UNDERFLOW,
105*b1d04644SDavid Schultz     float_flag_overflow  = FE_OVERFLOW,
106*b1d04644SDavid Schultz     float_flag_divbyzero = FE_DIVBYZERO,
107*b1d04644SDavid Schultz     float_flag_invalid   = FE_INVALID
1084ce26106SWarner Losh };
1094ce26106SWarner Losh 
1104ce26106SWarner Losh /*
1114ce26106SWarner Losh -------------------------------------------------------------------------------
1124ce26106SWarner Losh Routine to raise any or all of the software IEC/IEEE floating-point
1134ce26106SWarner Losh exception flags.
1144ce26106SWarner Losh -------------------------------------------------------------------------------
1154ce26106SWarner Losh */
116*b1d04644SDavid Schultz void float_raise( int );
1174ce26106SWarner Losh 
1184ce26106SWarner Losh /*
1194ce26106SWarner Losh -------------------------------------------------------------------------------
1204ce26106SWarner Losh Software IEC/IEEE integer-to-floating-point conversion routines.
1214ce26106SWarner Losh -------------------------------------------------------------------------------
1224ce26106SWarner Losh */
1234ce26106SWarner Losh float32 int32_to_float32( int );
1244ce26106SWarner Losh float64 int32_to_float64( int );
1254ce26106SWarner Losh #ifdef FLOATX80
1264ce26106SWarner Losh floatx80 int32_to_floatx80( int );
1274ce26106SWarner Losh #endif
1284ce26106SWarner Losh #ifdef FLOAT128
1294ce26106SWarner Losh float128 int32_to_float128( int );
1304ce26106SWarner Losh #endif
1314ce26106SWarner Losh #ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */
1324ce26106SWarner Losh float32 int64_to_float32( long long );
1334ce26106SWarner Losh float64 int64_to_float64( long long );
1344ce26106SWarner Losh #ifdef FLOATX80
1354ce26106SWarner Losh floatx80 int64_to_floatx80( long long );
1364ce26106SWarner Losh #endif
1374ce26106SWarner Losh #ifdef FLOAT128
1384ce26106SWarner Losh float128 int64_to_float128( long long );
1394ce26106SWarner Losh #endif
1404ce26106SWarner Losh #endif
1414ce26106SWarner Losh 
1424ce26106SWarner Losh /*
1434ce26106SWarner Losh -------------------------------------------------------------------------------
1444ce26106SWarner Losh Software IEC/IEEE single-precision conversion routines.
1454ce26106SWarner Losh -------------------------------------------------------------------------------
1464ce26106SWarner Losh */
1474ce26106SWarner Losh int float32_to_int32( float32 );
1484ce26106SWarner Losh int float32_to_int32_round_to_zero( float32 );
1494ce26106SWarner Losh #if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS)
1504ce26106SWarner Losh unsigned int float32_to_uint32_round_to_zero( float32 );
1514ce26106SWarner Losh #endif
1524ce26106SWarner Losh #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */
1534ce26106SWarner Losh long long float32_to_int64( float32 );
1544ce26106SWarner Losh long long float32_to_int64_round_to_zero( float32 );
1554ce26106SWarner Losh #endif
1564ce26106SWarner Losh float64 float32_to_float64( float32 );
1574ce26106SWarner Losh #ifdef FLOATX80
1584ce26106SWarner Losh floatx80 float32_to_floatx80( float32 );
1594ce26106SWarner Losh #endif
1604ce26106SWarner Losh #ifdef FLOAT128
1614ce26106SWarner Losh float128 float32_to_float128( float32 );
1624ce26106SWarner Losh #endif
1634ce26106SWarner Losh 
1644ce26106SWarner Losh /*
1654ce26106SWarner Losh -------------------------------------------------------------------------------
1664ce26106SWarner Losh Software IEC/IEEE single-precision operations.
1674ce26106SWarner Losh -------------------------------------------------------------------------------
1684ce26106SWarner Losh */
1694ce26106SWarner Losh float32 float32_round_to_int( float32 );
1704ce26106SWarner Losh float32 float32_add( float32, float32 );
1714ce26106SWarner Losh float32 float32_sub( float32, float32 );
1724ce26106SWarner Losh float32 float32_mul( float32, float32 );
1734ce26106SWarner Losh float32 float32_div( float32, float32 );
1744ce26106SWarner Losh float32 float32_rem( float32, float32 );
1754ce26106SWarner Losh float32 float32_sqrt( float32 );
1764ce26106SWarner Losh int float32_eq( float32, float32 );
1774ce26106SWarner Losh int float32_le( float32, float32 );
1784ce26106SWarner Losh int float32_lt( float32, float32 );
1794ce26106SWarner Losh int float32_eq_signaling( float32, float32 );
1804ce26106SWarner Losh int float32_le_quiet( float32, float32 );
1814ce26106SWarner Losh int float32_lt_quiet( float32, float32 );
1824ce26106SWarner Losh #ifndef SOFTFLOAT_FOR_GCC
1834ce26106SWarner Losh int float32_is_signaling_nan( float32 );
1844ce26106SWarner Losh #endif
1854ce26106SWarner Losh 
1864ce26106SWarner Losh /*
1874ce26106SWarner Losh -------------------------------------------------------------------------------
1884ce26106SWarner Losh Software IEC/IEEE double-precision conversion routines.
1894ce26106SWarner Losh -------------------------------------------------------------------------------
1904ce26106SWarner Losh */
1914ce26106SWarner Losh int float64_to_int32( float64 );
1924ce26106SWarner Losh int float64_to_int32_round_to_zero( float64 );
1934ce26106SWarner Losh #if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS)
1944ce26106SWarner Losh unsigned int float64_to_uint32_round_to_zero( float64 );
1954ce26106SWarner Losh #endif
1964ce26106SWarner Losh #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */
1974ce26106SWarner Losh long long float64_to_int64( float64 );
1984ce26106SWarner Losh long long float64_to_int64_round_to_zero( float64 );
1994ce26106SWarner Losh #endif
2004ce26106SWarner Losh float32 float64_to_float32( float64 );
2014ce26106SWarner Losh #ifdef FLOATX80
2024ce26106SWarner Losh floatx80 float64_to_floatx80( float64 );
2034ce26106SWarner Losh #endif
2044ce26106SWarner Losh #ifdef FLOAT128
2054ce26106SWarner Losh float128 float64_to_float128( float64 );
2064ce26106SWarner Losh #endif
2074ce26106SWarner Losh 
2084ce26106SWarner Losh /*
2094ce26106SWarner Losh -------------------------------------------------------------------------------
2104ce26106SWarner Losh Software IEC/IEEE double-precision operations.
2114ce26106SWarner Losh -------------------------------------------------------------------------------
2124ce26106SWarner Losh */
2134ce26106SWarner Losh float64 float64_round_to_int( float64 );
2144ce26106SWarner Losh float64 float64_add( float64, float64 );
2154ce26106SWarner Losh float64 float64_sub( float64, float64 );
2164ce26106SWarner Losh float64 float64_mul( float64, float64 );
2174ce26106SWarner Losh float64 float64_div( float64, float64 );
2184ce26106SWarner Losh float64 float64_rem( float64, float64 );
2194ce26106SWarner Losh float64 float64_sqrt( float64 );
2204ce26106SWarner Losh int float64_eq( float64, float64 );
2214ce26106SWarner Losh int float64_le( float64, float64 );
2224ce26106SWarner Losh int float64_lt( float64, float64 );
2234ce26106SWarner Losh int float64_eq_signaling( float64, float64 );
2244ce26106SWarner Losh int float64_le_quiet( float64, float64 );
2254ce26106SWarner Losh int float64_lt_quiet( float64, float64 );
2264ce26106SWarner Losh #ifndef SOFTFLOAT_FOR_GCC
2274ce26106SWarner Losh int float64_is_signaling_nan( float64 );
2284ce26106SWarner Losh #endif
2294ce26106SWarner Losh 
2304ce26106SWarner Losh #ifdef FLOATX80
2314ce26106SWarner Losh 
2324ce26106SWarner Losh /*
2334ce26106SWarner Losh -------------------------------------------------------------------------------
2344ce26106SWarner Losh Software IEC/IEEE extended double-precision conversion routines.
2354ce26106SWarner Losh -------------------------------------------------------------------------------
2364ce26106SWarner Losh */
2374ce26106SWarner Losh int floatx80_to_int32( floatx80 );
2384ce26106SWarner Losh int floatx80_to_int32_round_to_zero( floatx80 );
2394ce26106SWarner Losh long long floatx80_to_int64( floatx80 );
2404ce26106SWarner Losh long long floatx80_to_int64_round_to_zero( floatx80 );
2414ce26106SWarner Losh float32 floatx80_to_float32( floatx80 );
2424ce26106SWarner Losh float64 floatx80_to_float64( floatx80 );
2434ce26106SWarner Losh #ifdef FLOAT128
2444ce26106SWarner Losh float128 floatx80_to_float128( floatx80 );
2454ce26106SWarner Losh #endif
2464ce26106SWarner Losh 
2474ce26106SWarner Losh /*
2484ce26106SWarner Losh -------------------------------------------------------------------------------
2494ce26106SWarner Losh Software IEC/IEEE extended double-precision rounding precision.  Valid
2504ce26106SWarner Losh values are 32, 64, and 80.
2514ce26106SWarner Losh -------------------------------------------------------------------------------
2524ce26106SWarner Losh */
2534ce26106SWarner Losh extern int floatx80_rounding_precision;
2544ce26106SWarner Losh 
2554ce26106SWarner Losh /*
2564ce26106SWarner Losh -------------------------------------------------------------------------------
2574ce26106SWarner Losh Software IEC/IEEE extended double-precision operations.
2584ce26106SWarner Losh -------------------------------------------------------------------------------
2594ce26106SWarner Losh */
2604ce26106SWarner Losh floatx80 floatx80_round_to_int( floatx80 );
2614ce26106SWarner Losh floatx80 floatx80_add( floatx80, floatx80 );
2624ce26106SWarner Losh floatx80 floatx80_sub( floatx80, floatx80 );
2634ce26106SWarner Losh floatx80 floatx80_mul( floatx80, floatx80 );
2644ce26106SWarner Losh floatx80 floatx80_div( floatx80, floatx80 );
2654ce26106SWarner Losh floatx80 floatx80_rem( floatx80, floatx80 );
2664ce26106SWarner Losh floatx80 floatx80_sqrt( floatx80 );
2674ce26106SWarner Losh int floatx80_eq( floatx80, floatx80 );
2684ce26106SWarner Losh int floatx80_le( floatx80, floatx80 );
2694ce26106SWarner Losh int floatx80_lt( floatx80, floatx80 );
2704ce26106SWarner Losh int floatx80_eq_signaling( floatx80, floatx80 );
2714ce26106SWarner Losh int floatx80_le_quiet( floatx80, floatx80 );
2724ce26106SWarner Losh int floatx80_lt_quiet( floatx80, floatx80 );
2734ce26106SWarner Losh int floatx80_is_signaling_nan( floatx80 );
2744ce26106SWarner Losh 
2754ce26106SWarner Losh #endif
2764ce26106SWarner Losh 
2774ce26106SWarner Losh #ifdef FLOAT128
2784ce26106SWarner Losh 
2794ce26106SWarner Losh /*
2804ce26106SWarner Losh -------------------------------------------------------------------------------
2814ce26106SWarner Losh Software IEC/IEEE quadruple-precision conversion routines.
2824ce26106SWarner Losh -------------------------------------------------------------------------------
2834ce26106SWarner Losh */
2844ce26106SWarner Losh int float128_to_int32( float128 );
2854ce26106SWarner Losh int float128_to_int32_round_to_zero( float128 );
2864ce26106SWarner Losh long long float128_to_int64( float128 );
2874ce26106SWarner Losh long long float128_to_int64_round_to_zero( float128 );
2884ce26106SWarner Losh float32 float128_to_float32( float128 );
2894ce26106SWarner Losh float64 float128_to_float64( float128 );
2904ce26106SWarner Losh #ifdef FLOATX80
2914ce26106SWarner Losh floatx80 float128_to_floatx80( float128 );
2924ce26106SWarner Losh #endif
2934ce26106SWarner Losh 
2944ce26106SWarner Losh /*
2954ce26106SWarner Losh -------------------------------------------------------------------------------
2964ce26106SWarner Losh Software IEC/IEEE quadruple-precision operations.
2974ce26106SWarner Losh -------------------------------------------------------------------------------
2984ce26106SWarner Losh */
2994ce26106SWarner Losh float128 float128_round_to_int( float128 );
3004ce26106SWarner Losh float128 float128_add( float128, float128 );
3014ce26106SWarner Losh float128 float128_sub( float128, float128 );
3024ce26106SWarner Losh float128 float128_mul( float128, float128 );
3034ce26106SWarner Losh float128 float128_div( float128, float128 );
3044ce26106SWarner Losh float128 float128_rem( float128, float128 );
3054ce26106SWarner Losh float128 float128_sqrt( float128 );
3064ce26106SWarner Losh int float128_eq( float128, float128 );
3074ce26106SWarner Losh int float128_le( float128, float128 );
3084ce26106SWarner Losh int float128_lt( float128, float128 );
3094ce26106SWarner Losh int float128_eq_signaling( float128, float128 );
3104ce26106SWarner Losh int float128_le_quiet( float128, float128 );
3114ce26106SWarner Losh int float128_lt_quiet( float128, float128 );
3124ce26106SWarner Losh int float128_is_signaling_nan( float128 );
3134ce26106SWarner Losh 
3144ce26106SWarner Losh #endif
3154ce26106SWarner Losh 
316