1 2 /* 3 ============================================== 4 5 This C source fragment is part of the SoftFloa 6 Arithmetic Package, Release 2. 7 8 Written by John R. Hauser. This work was made 9 International Computer Science Institute, loca 10 Street, Berkeley, California 94704. Funding w 11 National Science Foundation under grant MIP-93 12 of this code was written as part of a project 13 processor in collaboration with the University 14 overseen by Profs. Nelson Morgan and John Wawr 15 is available through the Web page 16 http://www.jhauser.us/arithmetic/SoftFloat-2b/ 17 18 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. 19 has been made to avoid it, THIS SOFTWARE MAY C 20 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF TH 21 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAK 22 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISI 23 24 Derivative works are acceptable, even for comm 25 (1) they include prominent notice that the wor 26 include prominent notice akin to these three p 27 this code that are retained. 28 29 ============================================== 30 */ 31 32 /* 33 ---------------------------------------------- 34 Underflow tininess-detection mode, statically 35 (The declaration in `softfloat.h' must match t 36 ---------------------------------------------- 37 */ 38 int8 float_detect_tininess = float_tininess_af 39 40 /* 41 ---------------------------------------------- 42 Raises the exceptions specified by `flags'. F 43 defined here if desired. It is currently not 44 substitute a result value. If traps are not i 45 should be simply `float_exception_flags |= fla 46 47 ScottB: November 4, 1998 48 Moved this function out of softfloat-specializ 49 This effectively isolates all the changes requ 50 Linux kernel into fpmodule.c. Porting to NetB 51 fpmodule.c to integrate with the NetBSD kernel 52 ---------------------------------------------- 53 void float_raise( int8 flags ) 54 { 55 float_exception_flags |= flags; 56 } 57 */ 58 59 /* 60 ---------------------------------------------- 61 Internal canonical NaN format. 62 ---------------------------------------------- 63 */ 64 typedef struct { 65 flag sign; 66 bits64 high, low; 67 } commonNaNT; 68 69 /* 70 ---------------------------------------------- 71 The pattern for a default generated single-pre 72 ---------------------------------------------- 73 */ 74 #define float32_default_nan 0xFFFFFFFF 75 76 /* 77 ---------------------------------------------- 78 Returns 1 if the single-precision floating-poi 79 otherwise returns 0. 80 ---------------------------------------------- 81 */ 82 flag float32_is_nan( float32 a ) 83 { 84 85 return ( 0xFF000000 < (bits32) ( a<<1 ) ); 86 87 } 88 89 /* 90 ---------------------------------------------- 91 Returns 1 if the single-precision floating-poi 92 NaN; otherwise returns 0. 93 ---------------------------------------------- 94 */ 95 flag float32_is_signaling_nan( float32 a ) 96 { 97 98 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) 99 100 } 101 102 /* 103 ---------------------------------------------- 104 Returns the result of converting the single-pr 105 `a' to the canonical NaN format. If `a' is a 106 exception is raised. 107 ---------------------------------------------- 108 */ 109 static commonNaNT float32ToCommonNaN( float32 110 { 111 commonNaNT z; 112 113 if ( float32_is_signaling_nan( a ) ) float 114 z.sign = a>>31; 115 z.low = 0; 116 z.high = ( (bits64) a )<<41; 117 return z; 118 119 } 120 121 /* 122 ---------------------------------------------- 123 Returns the result of converting the canonical 124 precision floating-point format. 125 ---------------------------------------------- 126 */ 127 static float32 commonNaNToFloat32( commonNaNT 128 { 129 130 return ( ( (bits32) a.sign )<<31 ) | 0x7FC 131 132 } 133 134 /* 135 ---------------------------------------------- 136 Takes two single-precision floating-point valu 137 is a NaN, and returns the appropriate NaN resu 138 signaling NaN, the invalid exception is raised 139 ---------------------------------------------- 140 */ 141 static float32 propagateFloat32NaN( float32 a, 142 { 143 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsS 144 145 aIsNaN = float32_is_nan( a ); 146 aIsSignalingNaN = float32_is_signaling_nan 147 bIsNaN = float32_is_nan( b ); 148 bIsSignalingNaN = float32_is_signaling_nan 149 a |= 0x00400000; 150 b |= 0x00400000; 151 if ( aIsSignalingNaN | bIsSignalingNaN ) f 152 if ( aIsNaN ) { 153 return ( aIsSignalingNaN & bIsNaN ) ? 154 } 155 else { 156 return b; 157 } 158 159 } 160 161 /* 162 ---------------------------------------------- 163 The pattern for a default generated double-pre 164 ---------------------------------------------- 165 */ 166 #define float64_default_nan LIT64( 0xFFFFFFFFF 167 168 /* 169 ---------------------------------------------- 170 Returns 1 if the double-precision floating-poi 171 otherwise returns 0. 172 ---------------------------------------------- 173 */ 174 flag float64_is_nan( float64 a ) 175 { 176 177 return ( LIT64( 0xFFE0000000000000 ) < (bi 178 179 } 180 181 /* 182 ---------------------------------------------- 183 Returns 1 if the double-precision floating-poi 184 NaN; otherwise returns 0. 185 ---------------------------------------------- 186 */ 187 flag float64_is_signaling_nan( float64 a ) 188 { 189 190 return 191 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 192 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ) 193 194 } 195 196 /* 197 ---------------------------------------------- 198 Returns the result of converting the double-pr 199 `a' to the canonical NaN format. If `a' is a 200 exception is raised. 201 ---------------------------------------------- 202 */ 203 static commonNaNT float64ToCommonNaN( float64 204 { 205 commonNaNT z; 206 207 if ( float64_is_signaling_nan( a ) ) float 208 z.sign = a>>63; 209 z.low = 0; 210 z.high = a<<12; 211 return z; 212 213 } 214 215 /* 216 ---------------------------------------------- 217 Returns the result of converting the canonical 218 precision floating-point format. 219 ---------------------------------------------- 220 */ 221 static float64 commonNaNToFloat64( commonNaNT 222 { 223 224 return 225 ( ( (bits64) a.sign )<<63 ) 226 | LIT64( 0x7FF8000000000000 ) 227 | ( a.high>>12 ); 228 229 } 230 231 /* 232 ---------------------------------------------- 233 Takes two double-precision floating-point valu 234 is a NaN, and returns the appropriate NaN resu 235 signaling NaN, the invalid exception is raised 236 ---------------------------------------------- 237 */ 238 static float64 propagateFloat64NaN( float64 a, 239 { 240 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsS 241 242 aIsNaN = float64_is_nan( a ); 243 aIsSignalingNaN = float64_is_signaling_nan 244 bIsNaN = float64_is_nan( b ); 245 bIsSignalingNaN = float64_is_signaling_nan 246 a |= LIT64( 0x0008000000000000 ); 247 b |= LIT64( 0x0008000000000000 ); 248 if ( aIsSignalingNaN | bIsSignalingNaN ) f 249 if ( aIsNaN ) { 250 return ( aIsSignalingNaN & bIsNaN ) ? 251 } 252 else { 253 return b; 254 } 255 256 } 257 258 #ifdef FLOATX80 259 260 /* 261 ---------------------------------------------- 262 The pattern for a default generated extended d 263 `high' and `low' values hold the most- and lea 264 respectively. 265 ---------------------------------------------- 266 */ 267 #define floatx80_default_nan_high 0xFFFF 268 #define floatx80_default_nan_low LIT64( 0xFFF 269 270 /* 271 ---------------------------------------------- 272 Returns 1 if the extended double-precision flo 273 NaN; otherwise returns 0. 274 ---------------------------------------------- 275 */ 276 flag floatx80_is_nan( floatx80 a ) 277 { 278 279 return ( ( a.high & 0x7FFF ) == 0x7FFF ) & 280 281 } 282 283 /* 284 ---------------------------------------------- 285 Returns 1 if the extended double-precision flo 286 signaling NaN; otherwise returns 0. 287 ---------------------------------------------- 288 */ 289 flag floatx80_is_signaling_nan( floatx80 a ) 290 { 291 //register int lr; 292 bits64 aLow; 293 294 //__asm__("mov %0, lr" : : "g" (lr)); 295 //fp_printk("floatx80_is_signalling_nan() 296 aLow = a.low & ~ LIT64( 0x4000000000000000 297 return 298 ( ( a.high & 0x7FFF ) == 0x7FFF ) 299 && (bits64) ( aLow<<1 ) 300 && ( a.low == aLow ); 301 302 } 303 304 /* 305 ---------------------------------------------- 306 Returns the result of converting the extended 307 point NaN `a' to the canonical NaN format. If 308 invalid exception is raised. 309 ---------------------------------------------- 310 */ 311 static commonNaNT floatx80ToCommonNaN( floatx8 312 { 313 commonNaNT z; 314 315 if ( floatx80_is_signaling_nan( a ) ) floa 316 z.sign = a.high>>15; 317 z.low = 0; 318 z.high = a.low<<1; 319 return z; 320 321 } 322 323 /* 324 ---------------------------------------------- 325 Returns the result of converting the canonical 326 double-precision floating-point format. 327 ---------------------------------------------- 328 */ 329 static floatx80 commonNaNToFloatx80( commonNaN 330 { 331 floatx80 z; 332 333 z.low = LIT64( 0xC000000000000000 ) | ( a. 334 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7 335 z.__padding = 0; 336 return z; 337 338 } 339 340 /* 341 ---------------------------------------------- 342 Takes two extended double-precision floating-p 343 of which is a NaN, and returns the appropriate 344 `b' is a signaling NaN, the invalid exception 345 ---------------------------------------------- 346 */ 347 static floatx80 propagateFloatx80NaN( floatx80 348 { 349 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsS 350 351 aIsNaN = floatx80_is_nan( a ); 352 aIsSignalingNaN = floatx80_is_signaling_na 353 bIsNaN = floatx80_is_nan( b ); 354 bIsSignalingNaN = floatx80_is_signaling_na 355 a.low |= LIT64( 0xC000000000000000 ); 356 b.low |= LIT64( 0xC000000000000000 ); 357 if ( aIsSignalingNaN | bIsSignalingNaN ) f 358 if ( aIsNaN ) { 359 return ( aIsSignalingNaN & bIsNaN ) ? 360 } 361 else { 362 return b; 363 } 364 365 } 366 367 #endif
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.