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