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