xref: /freebsd/lib/libc/riscv/softfloat/softfloat.h (revision 2a63c3be)
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