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 *bedf142bSLennert Buytenhek typedef u32 float32; 55 *bedf142bSLennert Buytenhek typedef u64 float64; 56 1da177e4SLinus Torvalds typedef struct { 57 *bedf142bSLennert Buytenhek #ifdef __ARMEB__ 58 *bedf142bSLennert Buytenhek u16 __padding; 59 *bedf142bSLennert Buytenhek u16 high; 60 *bedf142bSLennert Buytenhek #else 61 *bedf142bSLennert Buytenhek u16 high; 62 *bedf142bSLennert Buytenhek u16 __padding; 63 *bedf142bSLennert Buytenhek #endif 64 *bedf142bSLennert Buytenhek u64 low; 65 1da177e4SLinus Torvalds } floatx80; 66 1da177e4SLinus Torvalds 67 1da177e4SLinus Torvalds /* 68 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 69 1da177e4SLinus Torvalds Software IEC/IEEE floating-point underflow tininess-detection mode. 70 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 71 1da177e4SLinus Torvalds */ 72 1da177e4SLinus Torvalds extern signed char float_detect_tininess; 73 1da177e4SLinus Torvalds enum { 74 1da177e4SLinus Torvalds float_tininess_after_rounding = 0, 75 1da177e4SLinus Torvalds float_tininess_before_rounding = 1 76 1da177e4SLinus Torvalds }; 77 1da177e4SLinus Torvalds 78 1da177e4SLinus Torvalds /* 79 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 80 1da177e4SLinus Torvalds Software IEC/IEEE floating-point rounding mode. 81 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 82 1da177e4SLinus Torvalds */ 83 f148af25SRichard Purdie //extern int8 float_rounding_mode; 84 1da177e4SLinus Torvalds enum { 85 1da177e4SLinus Torvalds float_round_nearest_even = 0, 86 1da177e4SLinus Torvalds float_round_to_zero = 1, 87 1da177e4SLinus Torvalds float_round_down = 2, 88 1da177e4SLinus Torvalds float_round_up = 3 89 1da177e4SLinus Torvalds }; 90 1da177e4SLinus Torvalds 91 1da177e4SLinus Torvalds /* 92 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 93 1da177e4SLinus Torvalds Software IEC/IEEE floating-point exception flags. 94 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 95 1da177e4SLinus Torvalds enum { 96 1da177e4SLinus Torvalds float_flag_inexact = 1, 97 1da177e4SLinus Torvalds float_flag_underflow = 2, 98 1da177e4SLinus Torvalds float_flag_overflow = 4, 99 1da177e4SLinus Torvalds float_flag_divbyzero = 8, 100 1da177e4SLinus Torvalds float_flag_invalid = 16 101 1da177e4SLinus Torvalds }; 102 1da177e4SLinus Torvalds 103 1da177e4SLinus Torvalds ScottB: November 4, 1998 104 1da177e4SLinus Torvalds Changed the enumeration to match the bit order in the FPA11. 105 1da177e4SLinus Torvalds */ 106 1da177e4SLinus Torvalds 107 1da177e4SLinus Torvalds enum { 108 1da177e4SLinus Torvalds float_flag_invalid = 1, 109 1da177e4SLinus Torvalds float_flag_divbyzero = 2, 110 1da177e4SLinus Torvalds float_flag_overflow = 4, 111 1da177e4SLinus Torvalds float_flag_underflow = 8, 112 1da177e4SLinus Torvalds float_flag_inexact = 16 113 1da177e4SLinus Torvalds }; 114 1da177e4SLinus Torvalds 115 1da177e4SLinus Torvalds /* 116 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 117 1da177e4SLinus Torvalds Routine to raise any or all of the software IEC/IEEE floating-point 118 1da177e4SLinus Torvalds exception flags. 119 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 120 1da177e4SLinus Torvalds */ 121 1da177e4SLinus Torvalds void float_raise( signed char ); 122 1da177e4SLinus Torvalds 123 1da177e4SLinus Torvalds /* 124 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 125 1da177e4SLinus Torvalds Software IEC/IEEE integer-to-floating-point conversion routines. 126 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 127 1da177e4SLinus Torvalds */ 128 f148af25SRichard Purdie float32 int32_to_float32( struct roundingData *, signed int ); 129 1da177e4SLinus Torvalds float64 int32_to_float64( signed int ); 130 1da177e4SLinus Torvalds #ifdef FLOATX80 131 1da177e4SLinus Torvalds floatx80 int32_to_floatx80( signed int ); 132 1da177e4SLinus Torvalds #endif 133 1da177e4SLinus Torvalds 134 1da177e4SLinus Torvalds /* 135 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 136 1da177e4SLinus Torvalds Software IEC/IEEE single-precision conversion routines. 137 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 138 1da177e4SLinus Torvalds */ 139 f148af25SRichard Purdie signed int float32_to_int32( struct roundingData *, float32 ); 140 1da177e4SLinus Torvalds signed int float32_to_int32_round_to_zero( float32 ); 141 1da177e4SLinus Torvalds float64 float32_to_float64( float32 ); 142 1da177e4SLinus Torvalds #ifdef FLOATX80 143 1da177e4SLinus Torvalds floatx80 float32_to_floatx80( float32 ); 144 1da177e4SLinus Torvalds #endif 145 1da177e4SLinus Torvalds 146 1da177e4SLinus Torvalds /* 147 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 148 1da177e4SLinus Torvalds Software IEC/IEEE single-precision operations. 149 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 150 1da177e4SLinus Torvalds */ 151 f148af25SRichard Purdie float32 float32_round_to_int( struct roundingData*, float32 ); 152 f148af25SRichard Purdie float32 float32_add( struct roundingData *, float32, float32 ); 153 f148af25SRichard Purdie float32 float32_sub( struct roundingData *, float32, float32 ); 154 f148af25SRichard Purdie float32 float32_mul( struct roundingData *, float32, float32 ); 155 f148af25SRichard Purdie float32 float32_div( struct roundingData *, float32, float32 ); 156 f148af25SRichard Purdie float32 float32_rem( struct roundingData *, float32, float32 ); 157 f148af25SRichard Purdie float32 float32_sqrt( struct roundingData*, float32 ); 158 1da177e4SLinus Torvalds char float32_eq( float32, float32 ); 159 1da177e4SLinus Torvalds char float32_le( float32, float32 ); 160 1da177e4SLinus Torvalds char float32_lt( float32, float32 ); 161 1da177e4SLinus Torvalds char float32_eq_signaling( float32, float32 ); 162 1da177e4SLinus Torvalds char float32_le_quiet( float32, float32 ); 163 1da177e4SLinus Torvalds char float32_lt_quiet( float32, float32 ); 164 1da177e4SLinus Torvalds char float32_is_signaling_nan( float32 ); 165 1da177e4SLinus Torvalds 166 1da177e4SLinus Torvalds /* 167 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 168 1da177e4SLinus Torvalds Software IEC/IEEE double-precision conversion routines. 169 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 170 1da177e4SLinus Torvalds */ 171 f148af25SRichard Purdie signed int float64_to_int32( struct roundingData *, float64 ); 172 1da177e4SLinus Torvalds signed int float64_to_int32_round_to_zero( float64 ); 173 f148af25SRichard Purdie float32 float64_to_float32( struct roundingData *, float64 ); 174 1da177e4SLinus Torvalds #ifdef FLOATX80 175 1da177e4SLinus Torvalds floatx80 float64_to_floatx80( float64 ); 176 1da177e4SLinus Torvalds #endif 177 1da177e4SLinus Torvalds 178 1da177e4SLinus Torvalds /* 179 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 180 1da177e4SLinus Torvalds Software IEC/IEEE double-precision operations. 181 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 182 1da177e4SLinus Torvalds */ 183 f148af25SRichard Purdie float64 float64_round_to_int( struct roundingData *, float64 ); 184 f148af25SRichard Purdie float64 float64_add( struct roundingData *, float64, float64 ); 185 f148af25SRichard Purdie float64 float64_sub( struct roundingData *, float64, float64 ); 186 f148af25SRichard Purdie float64 float64_mul( struct roundingData *, float64, float64 ); 187 f148af25SRichard Purdie float64 float64_div( struct roundingData *, float64, float64 ); 188 f148af25SRichard Purdie float64 float64_rem( struct roundingData *, float64, float64 ); 189 f148af25SRichard Purdie float64 float64_sqrt( struct roundingData *, float64 ); 190 1da177e4SLinus Torvalds char float64_eq( float64, float64 ); 191 1da177e4SLinus Torvalds char float64_le( float64, float64 ); 192 1da177e4SLinus Torvalds char float64_lt( float64, float64 ); 193 1da177e4SLinus Torvalds char float64_eq_signaling( float64, float64 ); 194 1da177e4SLinus Torvalds char float64_le_quiet( float64, float64 ); 195 1da177e4SLinus Torvalds char float64_lt_quiet( float64, float64 ); 196 1da177e4SLinus Torvalds char float64_is_signaling_nan( float64 ); 197 1da177e4SLinus Torvalds 198 1da177e4SLinus Torvalds #ifdef FLOATX80 199 1da177e4SLinus Torvalds 200 1da177e4SLinus Torvalds /* 201 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 202 1da177e4SLinus Torvalds Software IEC/IEEE extended double-precision conversion routines. 203 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 204 1da177e4SLinus Torvalds */ 205 f148af25SRichard Purdie signed int floatx80_to_int32( struct roundingData *, floatx80 ); 206 1da177e4SLinus Torvalds signed int floatx80_to_int32_round_to_zero( floatx80 ); 207 f148af25SRichard Purdie float32 floatx80_to_float32( struct roundingData *, floatx80 ); 208 f148af25SRichard Purdie float64 floatx80_to_float64( struct roundingData *, floatx80 ); 209 1da177e4SLinus Torvalds 210 1da177e4SLinus Torvalds /* 211 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 212 1da177e4SLinus Torvalds Software IEC/IEEE extended double-precision operations. 213 1da177e4SLinus Torvalds ------------------------------------------------------------------------------- 214 1da177e4SLinus Torvalds */ 215 f148af25SRichard Purdie floatx80 floatx80_round_to_int( struct roundingData *, floatx80 ); 216 f148af25SRichard Purdie floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 ); 217 f148af25SRichard Purdie floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 ); 218 f148af25SRichard Purdie floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 ); 219 f148af25SRichard Purdie floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 ); 220 f148af25SRichard Purdie floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 ); 221 f148af25SRichard Purdie floatx80 floatx80_sqrt( struct roundingData *, floatx80 ); 222 1da177e4SLinus Torvalds char floatx80_eq( floatx80, floatx80 ); 223 1da177e4SLinus Torvalds char floatx80_le( floatx80, floatx80 ); 224 1da177e4SLinus Torvalds char floatx80_lt( floatx80, floatx80 ); 225 1da177e4SLinus Torvalds char floatx80_eq_signaling( floatx80, floatx80 ); 226 1da177e4SLinus Torvalds char floatx80_le_quiet( floatx80, floatx80 ); 227 1da177e4SLinus Torvalds char floatx80_lt_quiet( floatx80, floatx80 ); 228 1da177e4SLinus Torvalds char floatx80_is_signaling_nan( floatx80 ); 229 1da177e4SLinus Torvalds 230 1da177e4SLinus Torvalds #endif 231 1da177e4SLinus Torvalds 232 1da177e4SLinus Torvalds static inline flag extractFloat32Sign(float32 a) 233 1da177e4SLinus Torvalds { 234 1da177e4SLinus Torvalds return a >> 31; 235 1da177e4SLinus Torvalds } 236 1da177e4SLinus Torvalds 237 1da177e4SLinus Torvalds static inline flag float32_eq_nocheck(float32 a, float32 b) 238 1da177e4SLinus Torvalds { 239 1da177e4SLinus Torvalds return (a == b) || ((bits32) ((a | b) << 1) == 0); 240 1da177e4SLinus Torvalds } 241 1da177e4SLinus Torvalds 242 1da177e4SLinus Torvalds static inline flag float32_lt_nocheck(float32 a, float32 b) 243 1da177e4SLinus Torvalds { 244 1da177e4SLinus Torvalds flag aSign, bSign; 245 1da177e4SLinus Torvalds 246 1da177e4SLinus Torvalds aSign = extractFloat32Sign(a); 247 1da177e4SLinus Torvalds bSign = extractFloat32Sign(b); 248 1da177e4SLinus Torvalds if (aSign != bSign) 249 1da177e4SLinus Torvalds return aSign && ((bits32) ((a | b) << 1) != 0); 250 1da177e4SLinus Torvalds return (a != b) && (aSign ^ (a < b)); 251 1da177e4SLinus Torvalds } 252 1da177e4SLinus Torvalds 253 1da177e4SLinus Torvalds static inline flag extractFloat64Sign(float64 a) 254 1da177e4SLinus Torvalds { 255 1da177e4SLinus Torvalds return a >> 63; 256 1da177e4SLinus Torvalds } 257 1da177e4SLinus Torvalds 258 1da177e4SLinus Torvalds static inline flag float64_eq_nocheck(float64 a, float64 b) 259 1da177e4SLinus Torvalds { 260 1da177e4SLinus Torvalds return (a == b) || ((bits64) ((a | b) << 1) == 0); 261 1da177e4SLinus Torvalds } 262 1da177e4SLinus Torvalds 263 1da177e4SLinus Torvalds static inline flag float64_lt_nocheck(float64 a, float64 b) 264 1da177e4SLinus Torvalds { 265 1da177e4SLinus Torvalds flag aSign, bSign; 266 1da177e4SLinus Torvalds 267 1da177e4SLinus Torvalds aSign = extractFloat64Sign(a); 268 1da177e4SLinus Torvalds bSign = extractFloat64Sign(b); 269 1da177e4SLinus Torvalds if (aSign != bSign) 270 1da177e4SLinus Torvalds return aSign && ((bits64) ((a | b) << 1) != 0); 271 1da177e4SLinus Torvalds return (a != b) && (aSign ^ (a < b)); 272 1da177e4SLinus Torvalds } 273 1da177e4SLinus Torvalds 274 6ec5e7f3SBen Dooks extern flag float32_is_nan( float32 a ); 275 6ec5e7f3SBen Dooks extern flag float64_is_nan( float64 a ); 276 6ec5e7f3SBen Dooks 277 1da177e4SLinus Torvalds #endif 278