1*7804dd52SRuslan Bukin /* $NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $ */ 2*7804dd52SRuslan Bukin 3*7804dd52SRuslan Bukin /* This is a derivative work. */ 4*7804dd52SRuslan Bukin 5*7804dd52SRuslan Bukin /* 6*7804dd52SRuslan Bukin =============================================================================== 7*7804dd52SRuslan Bukin 8*7804dd52SRuslan Bukin This C header file is part of the SoftFloat IEC/IEEE Floating-point 9*7804dd52SRuslan Bukin Arithmetic Package, Release 2a. 10*7804dd52SRuslan Bukin 11*7804dd52SRuslan Bukin Written by John R. Hauser. This work was made possible in part by the 12*7804dd52SRuslan Bukin International Computer Science Institute, located at Suite 600, 1947 Center 13*7804dd52SRuslan Bukin Street, Berkeley, California 94704. Funding was partially provided by the 14*7804dd52SRuslan Bukin National Science Foundation under grant MIP-9311980. The original version 15*7804dd52SRuslan Bukin of this code was written as part of a project to build a fixed-point vector 16*7804dd52SRuslan Bukin processor in collaboration with the University of California at Berkeley, 17*7804dd52SRuslan Bukin overseen by Profs. Nelson Morgan and John Wawrzynek. More information 18*7804dd52SRuslan Bukin is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ 19*7804dd52SRuslan Bukin arithmetic/SoftFloat.html'. 20*7804dd52SRuslan Bukin 21*7804dd52SRuslan Bukin THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 22*7804dd52SRuslan Bukin has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 23*7804dd52SRuslan Bukin TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 24*7804dd52SRuslan Bukin PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY 25*7804dd52SRuslan Bukin AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. 26*7804dd52SRuslan Bukin 27*7804dd52SRuslan Bukin Derivative works are acceptable, even for commercial purposes, so long as 28*7804dd52SRuslan Bukin (1) they include prominent notice that the work is derivative, and (2) they 29*7804dd52SRuslan Bukin include prominent notice akin to these four paragraphs for those parts of 30*7804dd52SRuslan Bukin this code that are retained. 31*7804dd52SRuslan Bukin 32*7804dd52SRuslan Bukin =============================================================================== 33*7804dd52SRuslan Bukin */ 34*7804dd52SRuslan Bukin 35*7804dd52SRuslan Bukin /* 36*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 37*7804dd52SRuslan Bukin The macro `FLOATX80' must be defined to enable the extended double-precision 38*7804dd52SRuslan Bukin floating-point format `floatx80'. If this macro is not defined, the 39*7804dd52SRuslan Bukin `floatx80' type will not be defined, and none of the functions that either 40*7804dd52SRuslan Bukin input or output the `floatx80' type will be defined. The same applies to 41*7804dd52SRuslan Bukin the `FLOAT128' macro and the quadruple-precision format `float128'. 42*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 43*7804dd52SRuslan Bukin */ 44*7804dd52SRuslan Bukin /* #define FLOATX80 */ 45*7804dd52SRuslan Bukin /* #define FLOAT128 */ 46*7804dd52SRuslan Bukin 47*7804dd52SRuslan Bukin #include <fenv.h> 48*7804dd52SRuslan Bukin 49*7804dd52SRuslan Bukin /* 50*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 51*7804dd52SRuslan Bukin Software IEC/IEEE floating-point types. 52*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 53*7804dd52SRuslan Bukin */ 54*7804dd52SRuslan Bukin typedef unsigned int float32; 55*7804dd52SRuslan Bukin typedef unsigned long long float64; 56*7804dd52SRuslan Bukin #ifdef FLOATX80 57*7804dd52SRuslan Bukin typedef struct { 58*7804dd52SRuslan Bukin unsigned short high; 59*7804dd52SRuslan Bukin unsigned long long low; 60*7804dd52SRuslan Bukin } floatx80; 61*7804dd52SRuslan Bukin #endif 62*7804dd52SRuslan Bukin #ifdef FLOAT128 63*7804dd52SRuslan Bukin typedef struct { 64*7804dd52SRuslan Bukin unsigned long long high, low; 65*7804dd52SRuslan Bukin } float128; 66*7804dd52SRuslan Bukin #endif 67*7804dd52SRuslan Bukin 68*7804dd52SRuslan Bukin /* 69*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 70*7804dd52SRuslan Bukin Software IEC/IEEE floating-point underflow tininess-detection mode. 71*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 72*7804dd52SRuslan Bukin */ 73*7804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC 74*7804dd52SRuslan Bukin extern int float_detect_tininess; 75*7804dd52SRuslan Bukin #endif 76*7804dd52SRuslan Bukin enum { 77*7804dd52SRuslan Bukin float_tininess_after_rounding = 0, 78*7804dd52SRuslan Bukin float_tininess_before_rounding = 1 79*7804dd52SRuslan Bukin }; 80*7804dd52SRuslan Bukin 81*7804dd52SRuslan Bukin /* 82*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 83*7804dd52SRuslan Bukin Software IEC/IEEE floating-point rounding mode. 84*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 85*7804dd52SRuslan Bukin */ 86*7804dd52SRuslan Bukin extern int float_rounding_mode; 87*7804dd52SRuslan Bukin enum { 88*7804dd52SRuslan Bukin float_round_nearest_even = FE_TONEAREST, 89*7804dd52SRuslan Bukin float_round_to_zero = FE_TOWARDZERO, 90*7804dd52SRuslan Bukin float_round_down = FE_DOWNWARD, 91*7804dd52SRuslan Bukin float_round_up = FE_UPWARD 92*7804dd52SRuslan Bukin }; 93*7804dd52SRuslan Bukin 94*7804dd52SRuslan Bukin /* 95*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 96*7804dd52SRuslan Bukin Software IEC/IEEE floating-point exception flags. 97*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 98*7804dd52SRuslan Bukin */ 99*7804dd52SRuslan Bukin extern int float_exception_flags; 100*7804dd52SRuslan Bukin extern int float_exception_mask; 101*7804dd52SRuslan Bukin enum { 102*7804dd52SRuslan Bukin float_flag_inexact = FE_INEXACT, 103*7804dd52SRuslan Bukin float_flag_underflow = FE_UNDERFLOW, 104*7804dd52SRuslan Bukin float_flag_overflow = FE_OVERFLOW, 105*7804dd52SRuslan Bukin float_flag_divbyzero = FE_DIVBYZERO, 106*7804dd52SRuslan Bukin float_flag_invalid = FE_INVALID 107*7804dd52SRuslan Bukin }; 108*7804dd52SRuslan Bukin 109*7804dd52SRuslan Bukin /* 110*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 111*7804dd52SRuslan Bukin Routine to raise any or all of the software IEC/IEEE floating-point 112*7804dd52SRuslan Bukin exception flags. 113*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 114*7804dd52SRuslan Bukin */ 115*7804dd52SRuslan Bukin void float_raise( int ); 116*7804dd52SRuslan Bukin 117*7804dd52SRuslan Bukin /* 118*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 119*7804dd52SRuslan Bukin Software IEC/IEEE integer-to-floating-point conversion routines. 120*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 121*7804dd52SRuslan Bukin */ 122*7804dd52SRuslan Bukin float32 int32_to_float32( int ); 123*7804dd52SRuslan Bukin float64 int32_to_float64( int ); 124*7804dd52SRuslan Bukin #ifdef FLOATX80 125*7804dd52SRuslan Bukin floatx80 int32_to_floatx80( int ); 126*7804dd52SRuslan Bukin #endif 127*7804dd52SRuslan Bukin #ifdef FLOAT128 128*7804dd52SRuslan Bukin float128 int32_to_float128( int ); 129*7804dd52SRuslan Bukin #endif 130*7804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */ 131*7804dd52SRuslan Bukin float32 int64_to_float32( long long ); 132*7804dd52SRuslan Bukin float64 int64_to_float64( long long ); 133*7804dd52SRuslan Bukin #ifdef FLOATX80 134*7804dd52SRuslan Bukin floatx80 int64_to_floatx80( long long ); 135*7804dd52SRuslan Bukin #endif 136*7804dd52SRuslan Bukin #ifdef FLOAT128 137*7804dd52SRuslan Bukin float128 int64_to_float128( long long ); 138*7804dd52SRuslan Bukin #endif 139*7804dd52SRuslan Bukin #endif 140*7804dd52SRuslan Bukin 141*7804dd52SRuslan Bukin /* 142*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 143*7804dd52SRuslan Bukin Software IEC/IEEE single-precision conversion routines. 144*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 145*7804dd52SRuslan Bukin */ 146*7804dd52SRuslan Bukin int float32_to_int32( float32 ); 147*7804dd52SRuslan Bukin int float32_to_int32_round_to_zero( float32 ); 148*7804dd52SRuslan Bukin #if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS) 149*7804dd52SRuslan Bukin unsigned int float32_to_uint32_round_to_zero( float32 ); 150*7804dd52SRuslan Bukin #endif 151*7804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ 152*7804dd52SRuslan Bukin long long float32_to_int64( float32 ); 153*7804dd52SRuslan Bukin long long float32_to_int64_round_to_zero( float32 ); 154*7804dd52SRuslan Bukin #endif 155*7804dd52SRuslan Bukin float64 float32_to_float64( float32 ); 156*7804dd52SRuslan Bukin #ifdef FLOATX80 157*7804dd52SRuslan Bukin floatx80 float32_to_floatx80( float32 ); 158*7804dd52SRuslan Bukin #endif 159*7804dd52SRuslan Bukin #ifdef FLOAT128 160*7804dd52SRuslan Bukin float128 float32_to_float128( float32 ); 161*7804dd52SRuslan Bukin #endif 162*7804dd52SRuslan Bukin 163*7804dd52SRuslan Bukin /* 164*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 165*7804dd52SRuslan Bukin Software IEC/IEEE single-precision operations. 166*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 167*7804dd52SRuslan Bukin */ 168*7804dd52SRuslan Bukin float32 float32_round_to_int( float32 ); 169*7804dd52SRuslan Bukin float32 float32_add( float32, float32 ); 170*7804dd52SRuslan Bukin float32 float32_sub( float32, float32 ); 171*7804dd52SRuslan Bukin float32 float32_mul( float32, float32 ); 172*7804dd52SRuslan Bukin float32 float32_div( float32, float32 ); 173*7804dd52SRuslan Bukin float32 float32_rem( float32, float32 ); 174*7804dd52SRuslan Bukin float32 float32_sqrt( float32 ); 175*7804dd52SRuslan Bukin int float32_eq( float32, float32 ); 176*7804dd52SRuslan Bukin int float32_le( float32, float32 ); 177*7804dd52SRuslan Bukin int float32_lt( float32, float32 ); 178*7804dd52SRuslan Bukin int float32_eq_signaling( float32, float32 ); 179*7804dd52SRuslan Bukin int float32_le_quiet( float32, float32 ); 180*7804dd52SRuslan Bukin int float32_lt_quiet( float32, float32 ); 181*7804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC 182*7804dd52SRuslan Bukin int float32_is_signaling_nan( float32 ); 183*7804dd52SRuslan Bukin #endif 184*7804dd52SRuslan Bukin 185*7804dd52SRuslan Bukin /* 186*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 187*7804dd52SRuslan Bukin Software IEC/IEEE double-precision conversion routines. 188*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 189*7804dd52SRuslan Bukin */ 190*7804dd52SRuslan Bukin int float64_to_int32( float64 ); 191*7804dd52SRuslan Bukin int float64_to_int32_round_to_zero( float64 ); 192*7804dd52SRuslan Bukin #if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS) 193*7804dd52SRuslan Bukin unsigned int float64_to_uint32_round_to_zero( float64 ); 194*7804dd52SRuslan Bukin #endif 195*7804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ 196*7804dd52SRuslan Bukin long long float64_to_int64( float64 ); 197*7804dd52SRuslan Bukin long long float64_to_int64_round_to_zero( float64 ); 198*7804dd52SRuslan Bukin #endif 199*7804dd52SRuslan Bukin float32 float64_to_float32( float64 ); 200*7804dd52SRuslan Bukin #ifdef FLOATX80 201*7804dd52SRuslan Bukin floatx80 float64_to_floatx80( float64 ); 202*7804dd52SRuslan Bukin #endif 203*7804dd52SRuslan Bukin #ifdef FLOAT128 204*7804dd52SRuslan Bukin float128 float64_to_float128( float64 ); 205*7804dd52SRuslan Bukin #endif 206*7804dd52SRuslan Bukin 207*7804dd52SRuslan Bukin /* 208*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 209*7804dd52SRuslan Bukin Software IEC/IEEE double-precision operations. 210*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 211*7804dd52SRuslan Bukin */ 212*7804dd52SRuslan Bukin float64 float64_round_to_int( float64 ); 213*7804dd52SRuslan Bukin float64 float64_add( float64, float64 ); 214*7804dd52SRuslan Bukin float64 float64_sub( float64, float64 ); 215*7804dd52SRuslan Bukin float64 float64_mul( float64, float64 ); 216*7804dd52SRuslan Bukin float64 float64_div( float64, float64 ); 217*7804dd52SRuslan Bukin float64 float64_rem( float64, float64 ); 218*7804dd52SRuslan Bukin float64 float64_sqrt( float64 ); 219*7804dd52SRuslan Bukin int float64_eq( float64, float64 ); 220*7804dd52SRuslan Bukin int float64_le( float64, float64 ); 221*7804dd52SRuslan Bukin int float64_lt( float64, float64 ); 222*7804dd52SRuslan Bukin int float64_eq_signaling( float64, float64 ); 223*7804dd52SRuslan Bukin int float64_le_quiet( float64, float64 ); 224*7804dd52SRuslan Bukin int float64_lt_quiet( float64, float64 ); 225*7804dd52SRuslan Bukin #ifndef SOFTFLOAT_FOR_GCC 226*7804dd52SRuslan Bukin int float64_is_signaling_nan( float64 ); 227*7804dd52SRuslan Bukin #endif 228*7804dd52SRuslan Bukin 229*7804dd52SRuslan Bukin #ifdef FLOATX80 230*7804dd52SRuslan Bukin 231*7804dd52SRuslan Bukin /* 232*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 233*7804dd52SRuslan Bukin Software IEC/IEEE extended double-precision conversion routines. 234*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 235*7804dd52SRuslan Bukin */ 236*7804dd52SRuslan Bukin int floatx80_to_int32( floatx80 ); 237*7804dd52SRuslan Bukin int floatx80_to_int32_round_to_zero( floatx80 ); 238*7804dd52SRuslan Bukin long long floatx80_to_int64( floatx80 ); 239*7804dd52SRuslan Bukin long long floatx80_to_int64_round_to_zero( floatx80 ); 240*7804dd52SRuslan Bukin float32 floatx80_to_float32( floatx80 ); 241*7804dd52SRuslan Bukin float64 floatx80_to_float64( floatx80 ); 242*7804dd52SRuslan Bukin #ifdef FLOAT128 243*7804dd52SRuslan Bukin float128 floatx80_to_float128( floatx80 ); 244*7804dd52SRuslan Bukin #endif 245*7804dd52SRuslan Bukin 246*7804dd52SRuslan Bukin /* 247*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 248*7804dd52SRuslan Bukin Software IEC/IEEE extended double-precision rounding precision. Valid 249*7804dd52SRuslan Bukin values are 32, 64, and 80. 250*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 251*7804dd52SRuslan Bukin */ 252*7804dd52SRuslan Bukin extern int floatx80_rounding_precision; 253*7804dd52SRuslan Bukin 254*7804dd52SRuslan Bukin /* 255*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 256*7804dd52SRuslan Bukin Software IEC/IEEE extended double-precision operations. 257*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 258*7804dd52SRuslan Bukin */ 259*7804dd52SRuslan Bukin floatx80 floatx80_round_to_int( floatx80 ); 260*7804dd52SRuslan Bukin floatx80 floatx80_add( floatx80, floatx80 ); 261*7804dd52SRuslan Bukin floatx80 floatx80_sub( floatx80, floatx80 ); 262*7804dd52SRuslan Bukin floatx80 floatx80_mul( floatx80, floatx80 ); 263*7804dd52SRuslan Bukin floatx80 floatx80_div( floatx80, floatx80 ); 264*7804dd52SRuslan Bukin floatx80 floatx80_rem( floatx80, floatx80 ); 265*7804dd52SRuslan Bukin floatx80 floatx80_sqrt( floatx80 ); 266*7804dd52SRuslan Bukin int floatx80_eq( floatx80, floatx80 ); 267*7804dd52SRuslan Bukin int floatx80_le( floatx80, floatx80 ); 268*7804dd52SRuslan Bukin int floatx80_lt( floatx80, floatx80 ); 269*7804dd52SRuslan Bukin int floatx80_eq_signaling( floatx80, floatx80 ); 270*7804dd52SRuslan Bukin int floatx80_le_quiet( floatx80, floatx80 ); 271*7804dd52SRuslan Bukin int floatx80_lt_quiet( floatx80, floatx80 ); 272*7804dd52SRuslan Bukin int floatx80_is_signaling_nan( floatx80 ); 273*7804dd52SRuslan Bukin 274*7804dd52SRuslan Bukin #endif 275*7804dd52SRuslan Bukin 276*7804dd52SRuslan Bukin #ifdef FLOAT128 277*7804dd52SRuslan Bukin 278*7804dd52SRuslan Bukin /* 279*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 280*7804dd52SRuslan Bukin Software IEC/IEEE quadruple-precision conversion routines. 281*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 282*7804dd52SRuslan Bukin */ 283*7804dd52SRuslan Bukin int float128_to_int32( float128 ); 284*7804dd52SRuslan Bukin int float128_to_int32_round_to_zero( float128 ); 285*7804dd52SRuslan Bukin long long float128_to_int64( float128 ); 286*7804dd52SRuslan Bukin long long float128_to_int64_round_to_zero( float128 ); 287*7804dd52SRuslan Bukin float32 float128_to_float32( float128 ); 288*7804dd52SRuslan Bukin float64 float128_to_float64( float128 ); 289*7804dd52SRuslan Bukin #ifdef FLOATX80 290*7804dd52SRuslan Bukin floatx80 float128_to_floatx80( float128 ); 291*7804dd52SRuslan Bukin #endif 292*7804dd52SRuslan Bukin 293*7804dd52SRuslan Bukin /* 294*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 295*7804dd52SRuslan Bukin Software IEC/IEEE quadruple-precision operations. 296*7804dd52SRuslan Bukin ------------------------------------------------------------------------------- 297*7804dd52SRuslan Bukin */ 298*7804dd52SRuslan Bukin float128 float128_round_to_int( float128 ); 299*7804dd52SRuslan Bukin float128 float128_add( float128, float128 ); 300*7804dd52SRuslan Bukin float128 float128_sub( float128, float128 ); 301*7804dd52SRuslan Bukin float128 float128_mul( float128, float128 ); 302*7804dd52SRuslan Bukin float128 float128_div( float128, float128 ); 303*7804dd52SRuslan Bukin float128 float128_rem( float128, float128 ); 304*7804dd52SRuslan Bukin float128 float128_sqrt( float128 ); 305*7804dd52SRuslan Bukin int float128_eq( float128, float128 ); 306*7804dd52SRuslan Bukin int float128_le( float128, float128 ); 307*7804dd52SRuslan Bukin int float128_lt( float128, float128 ); 308*7804dd52SRuslan Bukin int float128_eq_signaling( float128, float128 ); 309*7804dd52SRuslan Bukin int float128_le_quiet( float128, float128 ); 310*7804dd52SRuslan Bukin int float128_lt_quiet( float128, float128 ); 311*7804dd52SRuslan Bukin int float128_is_signaling_nan( float128 ); 312*7804dd52SRuslan Bukin 313*7804dd52SRuslan Bukin #endif 314*7804dd52SRuslan Bukin 315