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