1 1.14 nat /* $NetBSD: softfloat-specialize,v 1.14 2025/09/17 11:42:17 nat Exp $ */ 2 1.3 bjh21 3 1.3 bjh21 /* This is a derivative work. */ 4 1.1 bjh21 5 1.1 bjh21 /* 6 1.1 bjh21 =============================================================================== 7 1.1 bjh21 8 1.1 bjh21 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point 9 1.1 bjh21 Arithmetic Package, Release 2a. 10 1.1 bjh21 11 1.1 bjh21 Written by John R. Hauser. This work was made possible in part by the 12 1.1 bjh21 International Computer Science Institute, located at Suite 600, 1947 Center 13 1.1 bjh21 Street, Berkeley, California 94704. Funding was partially provided by the 14 1.1 bjh21 National Science Foundation under grant MIP-9311980. The original version 15 1.1 bjh21 of this code was written as part of a project to build a fixed-point vector 16 1.1 bjh21 processor in collaboration with the University of California at Berkeley, 17 1.1 bjh21 overseen by Profs. Nelson Morgan and John Wawrzynek. More information 18 1.1 bjh21 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ 19 1.1 bjh21 arithmetic/SoftFloat.html'. 20 1.1 bjh21 21 1.1 bjh21 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 22 1.1 bjh21 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 23 1.1 bjh21 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 24 1.1 bjh21 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY 25 1.1 bjh21 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. 26 1.1 bjh21 27 1.1 bjh21 Derivative works are acceptable, even for commercial purposes, so long as 28 1.1 bjh21 (1) they include prominent notice that the work is derivative, and (2) they 29 1.1 bjh21 include prominent notice akin to these four paragraphs for those parts of 30 1.1 bjh21 this code that are retained. 31 1.1 bjh21 32 1.1 bjh21 =============================================================================== 33 1.1 bjh21 */ 34 1.1 bjh21 35 1.3 bjh21 #include <signal.h> 36 1.5 martin #include <string.h> 37 1.5 martin #include <unistd.h> 38 1.3 bjh21 39 1.10 riastrad #include "reentrant.h" 40 1.10 riastrad 41 1.1 bjh21 /* 42 1.1 bjh21 ------------------------------------------------------------------------------- 43 1.1 bjh21 Underflow tininess-detection mode, statically initialized to default value. 44 1.1 bjh21 (The declaration in `softfloat.h' must match the `int8' type here.) 45 1.1 bjh21 ------------------------------------------------------------------------------- 46 1.1 bjh21 */ 47 1.1 bjh21 #ifdef SOFTFLOAT_FOR_GCC 48 1.1 bjh21 static 49 1.1 bjh21 #endif 50 1.1 bjh21 int8 float_detect_tininess = float_tininess_after_rounding; 51 1.1 bjh21 52 1.1 bjh21 /* 53 1.1 bjh21 ------------------------------------------------------------------------------- 54 1.1 bjh21 Raises the exceptions specified by `flags'. Floating-point traps can be 55 1.1 bjh21 defined here if desired. It is currently not possible for such a trap to 56 1.1 bjh21 substitute a result value. If traps are not implemented, this routine 57 1.1 bjh21 should be simply `float_exception_flags |= flags;'. 58 1.1 bjh21 ------------------------------------------------------------------------------- 59 1.1 bjh21 */ 60 1.6 martin #ifdef SOFTFLOAT_FOR_GCC 61 1.8 matt #ifndef set_float_exception_mask 62 1.6 martin #define float_exception_mask _softfloat_float_exception_mask 63 1.6 martin #endif 64 1.8 matt #endif 65 1.8 matt #ifndef set_float_exception_mask 66 1.3 bjh21 fp_except float_exception_mask = 0; 67 1.8 matt #endif 68 1.8 matt void 69 1.10 riastrad float_raise( fp_except newflags ) 70 1.1 bjh21 { 71 1.5 martin siginfo_t info; 72 1.10 riastrad struct sigaction sa; 73 1.10 riastrad sigset_t sigmask, osigmask; 74 1.10 riastrad fp_except flags; 75 1.1 bjh21 76 1.10 riastrad for (;;) { 77 1.8 matt #ifdef set_float_exception_mask 78 1.10 riastrad flags = newflags | set_float_exception_flags(newflags, 0); 79 1.8 matt #else 80 1.10 riastrad float_exception_flags |= newflags; 81 1.10 riastrad flags = float_exception_flags; 82 1.8 matt #endif 83 1.1 bjh21 84 1.10 riastrad /* 85 1.10 riastrad * If none of the sticky flags are trapped (i.e., enabled in 86 1.10 riastrad * float_exception_mask), we're done. Trapping is unusual and 87 1.10 riastrad * costly anyway, so take the non-trapping path as the fast 88 1.10 riastrad * path. 89 1.10 riastrad */ 90 1.10 riastrad flags &= float_exception_mask; 91 1.10 riastrad if (__predict_true(flags == 0)) 92 1.10 riastrad break; 93 1.10 riastrad 94 1.10 riastrad /* 95 1.10 riastrad * Block all signals while we figure out how to deliver a 96 1.10 riastrad * non-maskable (as a signal), non-ignorable SIGFPE, and obtain 97 1.10 riastrad * the current signal mask. 98 1.10 riastrad */ 99 1.10 riastrad sigfillset(&sigmask); 100 1.11 riastrad #ifdef _REENTRANT /* XXX PR lib/59401 */ 101 1.10 riastrad thr_sigsetmask(SIG_BLOCK, &sigmask, &osigmask); 102 1.11 riastrad #else 103 1.11 riastrad sigprocmask(SIG_BLOCK, &sigmask, &osigmask); 104 1.11 riastrad #endif 105 1.10 riastrad 106 1.10 riastrad /* 107 1.10 riastrad * Find the current signal disposition of SIGFPE. 108 1.10 riastrad */ 109 1.10 riastrad sigaction(SIGFPE, NULL, &sa); 110 1.10 riastrad 111 1.10 riastrad /* 112 1.10 riastrad * If SIGFPE is masked or ignored, unmask it and reset it to 113 1.10 riastrad * the default disposition to deliver the signal. 114 1.10 riastrad */ 115 1.10 riastrad if (sigismember(&osigmask, SIGFPE) || 116 1.10 riastrad ((sa.sa_flags & SA_SIGINFO) == 0 && 117 1.10 riastrad sa.sa_handler == SIG_IGN)) { 118 1.10 riastrad /* 119 1.10 riastrad * Prepare to unmask SIGFPE. This will take effect 120 1.10 riastrad * when we use thr_sigsetmask(SIG_SETMASK, ...) below, 121 1.10 riastrad * once the signal has been queued, so that it happens 122 1.10 riastrad * atomically with respect to other signal delivery. 123 1.10 riastrad */ 124 1.10 riastrad sigdelset(&osigmask, SIGFPE); 125 1.10 riastrad 126 1.10 riastrad /* 127 1.10 riastrad * Reset SIGFPE to the default disposition, which is to 128 1.10 riastrad * terminate the process. 129 1.10 riastrad */ 130 1.10 riastrad memset(&sa, 0, sizeof(sa)); 131 1.10 riastrad sa.sa_handler = SIG_DFL; 132 1.10 riastrad sigemptyset(&sa.sa_mask); 133 1.10 riastrad sa.sa_flags = 0; 134 1.10 riastrad sigaction(SIGFPE, &sa, NULL); 135 1.10 riastrad } 136 1.10 riastrad 137 1.10 riastrad /* 138 1.10 riastrad * Queue the signal for delivery. It won't trigger the signal 139 1.10 riastrad * handler yet, because it's still masked, but as soon as we 140 1.10 riastrad * unmask it either the process will terminate or the signal 141 1.10 riastrad * handler will be called. 142 1.10 riastrad */ 143 1.5 martin memset(&info, 0, sizeof info); 144 1.5 martin info.si_signo = SIGFPE; 145 1.5 martin info.si_pid = getpid(); 146 1.5 martin info.si_uid = geteuid(); 147 1.5 martin if (flags & float_flag_underflow) 148 1.5 martin info.si_code = FPE_FLTUND; 149 1.5 martin else if (flags & float_flag_overflow) 150 1.5 martin info.si_code = FPE_FLTOVF; 151 1.5 martin else if (flags & float_flag_divbyzero) 152 1.5 martin info.si_code = FPE_FLTDIV; 153 1.5 martin else if (flags & float_flag_invalid) 154 1.5 martin info.si_code = FPE_FLTINV; 155 1.5 martin else if (flags & float_flag_inexact) 156 1.5 martin info.si_code = FPE_FLTRES; 157 1.5 martin sigqueueinfo(getpid(), &info); 158 1.10 riastrad 159 1.10 riastrad /* 160 1.10 riastrad * Restore the old signal mask, except with SIGFPE unmasked 161 1.10 riastrad * even if it was masked before. 162 1.10 riastrad * 163 1.10 riastrad * At this point, either the process will terminate (if SIGFPE 164 1.10 riastrad * had or now has the default disposition) or the signal 165 1.10 riastrad * handler will be called (if SIGFPE had a non-default, 166 1.10 riastrad * non-ignored disposition). 167 1.10 riastrad * 168 1.10 riastrad * If the signal handler returns, it can't change the set of 169 1.10 riastrad * exceptions raised by this floating-point operation -- but it 170 1.10 riastrad * can change the sticky set from previous operations, and it 171 1.10 riastrad * can change the set of exceptions that are trapped, so loop 172 1.10 riastrad * around; next time we might make progress instead of calling 173 1.10 riastrad * the signal handler again. 174 1.10 riastrad */ 175 1.11 riastrad #ifdef _REENTRANT /* XXX PR lib/59401 */ 176 1.10 riastrad thr_sigsetmask(SIG_SETMASK, &osigmask, NULL); 177 1.11 riastrad #else 178 1.11 riastrad sigprocmask(SIG_SETMASK, &osigmask, NULL); 179 1.11 riastrad #endif 180 1.3 bjh21 } 181 1.1 bjh21 } 182 1.6 martin #undef float_exception_mask 183 1.1 bjh21 184 1.1 bjh21 /* 185 1.1 bjh21 ------------------------------------------------------------------------------- 186 1.1 bjh21 Internal canonical NaN format. 187 1.1 bjh21 ------------------------------------------------------------------------------- 188 1.1 bjh21 */ 189 1.1 bjh21 typedef struct { 190 1.1 bjh21 flag sign; 191 1.1 bjh21 bits64 high, low; 192 1.1 bjh21 } commonNaNT; 193 1.1 bjh21 194 1.1 bjh21 /* 195 1.1 bjh21 ------------------------------------------------------------------------------- 196 1.1 bjh21 The pattern for a default generated single-precision NaN. 197 1.1 bjh21 ------------------------------------------------------------------------------- 198 1.1 bjh21 */ 199 1.1 bjh21 #define float32_default_nan 0xFFFFFFFF 200 1.1 bjh21 201 1.1 bjh21 /* 202 1.1 bjh21 ------------------------------------------------------------------------------- 203 1.1 bjh21 Returns 1 if the single-precision floating-point value `a' is a NaN; 204 1.1 bjh21 otherwise returns 0. 205 1.1 bjh21 ------------------------------------------------------------------------------- 206 1.1 bjh21 */ 207 1.1 bjh21 #ifdef SOFTFLOAT_FOR_GCC 208 1.1 bjh21 static 209 1.1 bjh21 #endif 210 1.1 bjh21 flag float32_is_nan( float32 a ) 211 1.1 bjh21 { 212 1.1 bjh21 213 1.7 christos return ( (bits32)0xFF000000 < (bits32) ( a<<1 ) ); 214 1.1 bjh21 215 1.1 bjh21 } 216 1.1 bjh21 217 1.1 bjh21 /* 218 1.1 bjh21 ------------------------------------------------------------------------------- 219 1.1 bjh21 Returns 1 if the single-precision floating-point value `a' is a signaling 220 1.1 bjh21 NaN; otherwise returns 0. 221 1.1 bjh21 ------------------------------------------------------------------------------- 222 1.1 bjh21 */ 223 1.9 matt #if defined(SOFTFLOAT_FOR_GCC) \ 224 1.9 matt && !defined(SOFTFLOATAARCH64_FOR_GCC) \ 225 1.9 matt && !defined(SOFTFLOATSPARC64_FOR_GCC) \ 226 1.9 matt && !defined(SOFTFLOATM68K_FOR_GCC) 227 1.1 bjh21 static 228 1.1 bjh21 #endif 229 1.1 bjh21 flag float32_is_signaling_nan( float32 a ) 230 1.1 bjh21 { 231 1.1 bjh21 232 1.1 bjh21 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 233 1.1 bjh21 234 1.1 bjh21 } 235 1.1 bjh21 236 1.1 bjh21 /* 237 1.1 bjh21 ------------------------------------------------------------------------------- 238 1.1 bjh21 Returns the result of converting the single-precision floating-point NaN 239 1.1 bjh21 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 240 1.1 bjh21 exception is raised. 241 1.1 bjh21 ------------------------------------------------------------------------------- 242 1.1 bjh21 */ 243 1.1 bjh21 static commonNaNT float32ToCommonNaN( float32 a ) 244 1.1 bjh21 { 245 1.1 bjh21 commonNaNT z; 246 1.1 bjh21 247 1.1 bjh21 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 248 1.1 bjh21 z.sign = a>>31; 249 1.1 bjh21 z.low = 0; 250 1.1 bjh21 z.high = ( (bits64) a )<<41; 251 1.1 bjh21 return z; 252 1.1 bjh21 253 1.1 bjh21 } 254 1.1 bjh21 255 1.1 bjh21 /* 256 1.1 bjh21 ------------------------------------------------------------------------------- 257 1.1 bjh21 Returns the result of converting the canonical NaN `a' to the single- 258 1.1 bjh21 precision floating-point format. 259 1.1 bjh21 ------------------------------------------------------------------------------- 260 1.1 bjh21 */ 261 1.1 bjh21 static float32 commonNaNToFloat32( commonNaNT a ) 262 1.1 bjh21 { 263 1.1 bjh21 264 1.7 christos return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | (bits32)( a.high>>41 ); 265 1.1 bjh21 266 1.1 bjh21 } 267 1.1 bjh21 268 1.1 bjh21 /* 269 1.1 bjh21 ------------------------------------------------------------------------------- 270 1.1 bjh21 Takes two single-precision floating-point values `a' and `b', one of which 271 1.1 bjh21 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 272 1.1 bjh21 signaling NaN, the invalid exception is raised. 273 1.1 bjh21 ------------------------------------------------------------------------------- 274 1.1 bjh21 */ 275 1.1 bjh21 static float32 propagateFloat32NaN( float32 a, float32 b ) 276 1.1 bjh21 { 277 1.1 bjh21 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 278 1.1 bjh21 279 1.1 bjh21 aIsNaN = float32_is_nan( a ); 280 1.1 bjh21 aIsSignalingNaN = float32_is_signaling_nan( a ); 281 1.1 bjh21 bIsNaN = float32_is_nan( b ); 282 1.1 bjh21 bIsSignalingNaN = float32_is_signaling_nan( b ); 283 1.1 bjh21 a |= 0x00400000; 284 1.1 bjh21 b |= 0x00400000; 285 1.1 bjh21 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 286 1.1 bjh21 if ( aIsNaN ) { 287 1.1 bjh21 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 288 1.1 bjh21 } 289 1.1 bjh21 else { 290 1.1 bjh21 return b; 291 1.1 bjh21 } 292 1.1 bjh21 293 1.1 bjh21 } 294 1.1 bjh21 295 1.1 bjh21 /* 296 1.1 bjh21 ------------------------------------------------------------------------------- 297 1.1 bjh21 The pattern for a default generated double-precision NaN. 298 1.1 bjh21 ------------------------------------------------------------------------------- 299 1.1 bjh21 */ 300 1.1 bjh21 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) 301 1.1 bjh21 302 1.1 bjh21 /* 303 1.1 bjh21 ------------------------------------------------------------------------------- 304 1.1 bjh21 Returns 1 if the double-precision floating-point value `a' is a NaN; 305 1.1 bjh21 otherwise returns 0. 306 1.1 bjh21 ------------------------------------------------------------------------------- 307 1.1 bjh21 */ 308 1.1 bjh21 #ifdef SOFTFLOAT_FOR_GCC 309 1.1 bjh21 static 310 1.1 bjh21 #endif 311 1.1 bjh21 flag float64_is_nan( float64 a ) 312 1.1 bjh21 { 313 1.1 bjh21 314 1.7 christos return ( (bits64)LIT64( 0xFFE0000000000000 ) < 315 1.1 bjh21 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) ); 316 1.1 bjh21 317 1.1 bjh21 } 318 1.1 bjh21 319 1.1 bjh21 /* 320 1.1 bjh21 ------------------------------------------------------------------------------- 321 1.1 bjh21 Returns 1 if the double-precision floating-point value `a' is a signaling 322 1.1 bjh21 NaN; otherwise returns 0. 323 1.1 bjh21 ------------------------------------------------------------------------------- 324 1.1 bjh21 */ 325 1.9 matt #if defined(SOFTFLOAT_FOR_GCC) \ 326 1.9 matt && !defined(SOFTFLOATAARCH64_FOR_GCC) \ 327 1.9 matt && !defined(SOFTFLOATSPARC64_FOR_GCC) \ 328 1.9 matt && !defined(SOFTFLOATM68K_FOR_GCC) 329 1.1 bjh21 static 330 1.1 bjh21 #endif 331 1.1 bjh21 flag float64_is_signaling_nan( float64 a ) 332 1.1 bjh21 { 333 1.1 bjh21 334 1.1 bjh21 return 335 1.1 bjh21 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE ) 336 1.1 bjh21 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) ); 337 1.1 bjh21 338 1.1 bjh21 } 339 1.1 bjh21 340 1.1 bjh21 /* 341 1.1 bjh21 ------------------------------------------------------------------------------- 342 1.1 bjh21 Returns the result of converting the double-precision floating-point NaN 343 1.1 bjh21 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 344 1.1 bjh21 exception is raised. 345 1.1 bjh21 ------------------------------------------------------------------------------- 346 1.1 bjh21 */ 347 1.1 bjh21 static commonNaNT float64ToCommonNaN( float64 a ) 348 1.1 bjh21 { 349 1.1 bjh21 commonNaNT z; 350 1.1 bjh21 351 1.1 bjh21 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 352 1.7 christos z.sign = (flag)(FLOAT64_DEMANGLE(a)>>63); 353 1.1 bjh21 z.low = 0; 354 1.1 bjh21 z.high = FLOAT64_DEMANGLE(a)<<12; 355 1.1 bjh21 return z; 356 1.1 bjh21 357 1.1 bjh21 } 358 1.1 bjh21 359 1.1 bjh21 /* 360 1.1 bjh21 ------------------------------------------------------------------------------- 361 1.1 bjh21 Returns the result of converting the canonical NaN `a' to the double- 362 1.1 bjh21 precision floating-point format. 363 1.1 bjh21 ------------------------------------------------------------------------------- 364 1.1 bjh21 */ 365 1.1 bjh21 static float64 commonNaNToFloat64( commonNaNT a ) 366 1.1 bjh21 { 367 1.1 bjh21 368 1.1 bjh21 return FLOAT64_MANGLE( 369 1.1 bjh21 ( ( (bits64) a.sign )<<63 ) 370 1.1 bjh21 | LIT64( 0x7FF8000000000000 ) 371 1.1 bjh21 | ( a.high>>12 ) ); 372 1.1 bjh21 373 1.1 bjh21 } 374 1.1 bjh21 375 1.1 bjh21 /* 376 1.1 bjh21 ------------------------------------------------------------------------------- 377 1.1 bjh21 Takes two double-precision floating-point values `a' and `b', one of which 378 1.1 bjh21 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 379 1.1 bjh21 signaling NaN, the invalid exception is raised. 380 1.1 bjh21 ------------------------------------------------------------------------------- 381 1.1 bjh21 */ 382 1.1 bjh21 static float64 propagateFloat64NaN( float64 a, float64 b ) 383 1.1 bjh21 { 384 1.1 bjh21 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 385 1.1 bjh21 386 1.1 bjh21 aIsNaN = float64_is_nan( a ); 387 1.1 bjh21 aIsSignalingNaN = float64_is_signaling_nan( a ); 388 1.1 bjh21 bIsNaN = float64_is_nan( b ); 389 1.1 bjh21 bIsSignalingNaN = float64_is_signaling_nan( b ); 390 1.1 bjh21 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); 391 1.1 bjh21 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); 392 1.1 bjh21 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 393 1.1 bjh21 if ( aIsNaN ) { 394 1.1 bjh21 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 395 1.1 bjh21 } 396 1.1 bjh21 else { 397 1.1 bjh21 return b; 398 1.1 bjh21 } 399 1.1 bjh21 400 1.1 bjh21 } 401 1.1 bjh21 402 1.1 bjh21 #ifdef FLOATX80 403 1.1 bjh21 404 1.1 bjh21 /* 405 1.1 bjh21 ------------------------------------------------------------------------------- 406 1.1 bjh21 The pattern for a default generated extended double-precision NaN. The 407 1.1 bjh21 `high' and `low' values hold the most- and least-significant bits, 408 1.1 bjh21 respectively. 409 1.1 bjh21 ------------------------------------------------------------------------------- 410 1.1 bjh21 */ 411 1.1 bjh21 #define floatx80_default_nan_high 0xFFFF 412 1.1 bjh21 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 413 1.1 bjh21 414 1.1 bjh21 /* 415 1.1 bjh21 ------------------------------------------------------------------------------- 416 1.1 bjh21 Returns 1 if the extended double-precision floating-point value `a' is a 417 1.1 bjh21 NaN; otherwise returns 0. 418 1.1 bjh21 ------------------------------------------------------------------------------- 419 1.1 bjh21 */ 420 1.1 bjh21 flag floatx80_is_nan( floatx80 a ) 421 1.1 bjh21 { 422 1.1 bjh21 423 1.13 nat return (((a.high >> X80SHIFT) & 0x7FFF) == 0x7FFF) && (bits64)(a.low<<1); 424 1.1 bjh21 425 1.1 bjh21 } 426 1.1 bjh21 427 1.1 bjh21 /* 428 1.1 bjh21 ------------------------------------------------------------------------------- 429 1.1 bjh21 Returns 1 if the extended double-precision floating-point value `a' is a 430 1.1 bjh21 signaling NaN; otherwise returns 0. 431 1.1 bjh21 ------------------------------------------------------------------------------- 432 1.1 bjh21 */ 433 1.1 bjh21 flag floatx80_is_signaling_nan( floatx80 a ) 434 1.1 bjh21 { 435 1.1 bjh21 bits64 aLow; 436 1.1 bjh21 437 1.1 bjh21 aLow = a.low & ~ LIT64( 0x4000000000000000 ); 438 1.1 bjh21 return 439 1.13 nat ( ( (a.high >> X80SHIFT) & 0x7FFF ) == 0x7FFF ) 440 1.1 bjh21 && (bits64) ( aLow<<1 ) 441 1.1 bjh21 && ( a.low == aLow ); 442 1.1 bjh21 443 1.1 bjh21 } 444 1.1 bjh21 445 1.12 nat #ifndef SOFTFLOAT_BITS32 446 1.1 bjh21 /* 447 1.1 bjh21 ------------------------------------------------------------------------------- 448 1.1 bjh21 Returns the result of converting the extended double-precision floating- 449 1.1 bjh21 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 450 1.1 bjh21 invalid exception is raised. 451 1.1 bjh21 ------------------------------------------------------------------------------- 452 1.1 bjh21 */ 453 1.1 bjh21 static commonNaNT floatx80ToCommonNaN( floatx80 a ) 454 1.1 bjh21 { 455 1.1 bjh21 commonNaNT z; 456 1.1 bjh21 457 1.1 bjh21 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 458 1.14 nat z.sign = a.high>>(15 + X80SHIFT); 459 1.14 nat z.low = a.low<<1; 460 1.14 nat z.high = (a.high>>X80SHIFT) & 0x7FFF; 461 1.1 bjh21 return z; 462 1.1 bjh21 463 1.1 bjh21 } 464 1.1 bjh21 465 1.1 bjh21 /* 466 1.1 bjh21 ------------------------------------------------------------------------------- 467 1.1 bjh21 Returns the result of converting the canonical NaN `a' to the extended 468 1.1 bjh21 double-precision floating-point format. 469 1.1 bjh21 ------------------------------------------------------------------------------- 470 1.1 bjh21 */ 471 1.1 bjh21 static floatx80 commonNaNToFloatx80( commonNaNT a ) 472 1.1 bjh21 { 473 1.1 bjh21 floatx80 z; 474 1.1 bjh21 475 1.14 nat z.low = LIT64( 0xC000000000000000 ) | ( a.low ); 476 1.14 nat z.high = (( ( (bits16) a.sign )<<15 ) | 0x7FFF) << X80SHIFT; 477 1.1 bjh21 return z; 478 1.1 bjh21 479 1.1 bjh21 } 480 1.1 bjh21 481 1.1 bjh21 /* 482 1.1 bjh21 ------------------------------------------------------------------------------- 483 1.1 bjh21 Takes two extended double-precision floating-point values `a' and `b', one 484 1.1 bjh21 of which is a NaN, and returns the appropriate NaN result. If either `a' or 485 1.1 bjh21 `b' is a signaling NaN, the invalid exception is raised. 486 1.1 bjh21 ------------------------------------------------------------------------------- 487 1.1 bjh21 */ 488 1.1 bjh21 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) 489 1.1 bjh21 { 490 1.1 bjh21 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 491 1.1 bjh21 492 1.1 bjh21 aIsNaN = floatx80_is_nan( a ); 493 1.1 bjh21 aIsSignalingNaN = floatx80_is_signaling_nan( a ); 494 1.1 bjh21 bIsNaN = floatx80_is_nan( b ); 495 1.1 bjh21 bIsSignalingNaN = floatx80_is_signaling_nan( b ); 496 1.1 bjh21 a.low |= LIT64( 0xC000000000000000 ); 497 1.1 bjh21 b.low |= LIT64( 0xC000000000000000 ); 498 1.1 bjh21 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 499 1.1 bjh21 if ( aIsNaN ) { 500 1.1 bjh21 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 501 1.1 bjh21 } 502 1.1 bjh21 else { 503 1.1 bjh21 return b; 504 1.1 bjh21 } 505 1.1 bjh21 506 1.1 bjh21 } 507 1.1 bjh21 508 1.1 bjh21 #endif 509 1.12 nat #endif 510 1.1 bjh21 511 1.1 bjh21 #ifdef FLOAT128 512 1.1 bjh21 513 1.1 bjh21 /* 514 1.1 bjh21 ------------------------------------------------------------------------------- 515 1.1 bjh21 The pattern for a default generated quadruple-precision NaN. The `high' and 516 1.1 bjh21 `low' values hold the most- and least-significant bits, respectively. 517 1.1 bjh21 ------------------------------------------------------------------------------- 518 1.1 bjh21 */ 519 1.1 bjh21 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) 520 1.1 bjh21 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 521 1.1 bjh21 522 1.1 bjh21 /* 523 1.1 bjh21 ------------------------------------------------------------------------------- 524 1.1 bjh21 Returns 1 if the quadruple-precision floating-point value `a' is a NaN; 525 1.1 bjh21 otherwise returns 0. 526 1.1 bjh21 ------------------------------------------------------------------------------- 527 1.1 bjh21 */ 528 1.1 bjh21 flag float128_is_nan( float128 a ) 529 1.1 bjh21 { 530 1.1 bjh21 531 1.1 bjh21 return 532 1.7 christos ( (bits64)LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 533 1.1 bjh21 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 534 1.1 bjh21 535 1.1 bjh21 } 536 1.1 bjh21 537 1.1 bjh21 /* 538 1.1 bjh21 ------------------------------------------------------------------------------- 539 1.1 bjh21 Returns 1 if the quadruple-precision floating-point value `a' is a 540 1.1 bjh21 signaling NaN; otherwise returns 0. 541 1.1 bjh21 ------------------------------------------------------------------------------- 542 1.1 bjh21 */ 543 1.1 bjh21 flag float128_is_signaling_nan( float128 a ) 544 1.1 bjh21 { 545 1.1 bjh21 546 1.1 bjh21 return 547 1.1 bjh21 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 548 1.1 bjh21 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 549 1.1 bjh21 550 1.1 bjh21 } 551 1.1 bjh21 552 1.1 bjh21 /* 553 1.1 bjh21 ------------------------------------------------------------------------------- 554 1.1 bjh21 Returns the result of converting the quadruple-precision floating-point NaN 555 1.1 bjh21 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 556 1.1 bjh21 exception is raised. 557 1.1 bjh21 ------------------------------------------------------------------------------- 558 1.1 bjh21 */ 559 1.1 bjh21 static commonNaNT float128ToCommonNaN( float128 a ) 560 1.1 bjh21 { 561 1.1 bjh21 commonNaNT z; 562 1.1 bjh21 563 1.1 bjh21 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 564 1.7 christos z.sign = (flag)(a.high>>63); 565 1.1 bjh21 shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 566 1.1 bjh21 return z; 567 1.1 bjh21 568 1.1 bjh21 } 569 1.1 bjh21 570 1.1 bjh21 /* 571 1.1 bjh21 ------------------------------------------------------------------------------- 572 1.1 bjh21 Returns the result of converting the canonical NaN `a' to the quadruple- 573 1.1 bjh21 precision floating-point format. 574 1.1 bjh21 ------------------------------------------------------------------------------- 575 1.1 bjh21 */ 576 1.1 bjh21 static float128 commonNaNToFloat128( commonNaNT a ) 577 1.1 bjh21 { 578 1.1 bjh21 float128 z; 579 1.1 bjh21 580 1.1 bjh21 shift128Right( a.high, a.low, 16, &z.high, &z.low ); 581 1.1 bjh21 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); 582 1.1 bjh21 return z; 583 1.1 bjh21 584 1.1 bjh21 } 585 1.1 bjh21 586 1.1 bjh21 /* 587 1.1 bjh21 ------------------------------------------------------------------------------- 588 1.1 bjh21 Takes two quadruple-precision floating-point values `a' and `b', one of 589 1.1 bjh21 which is a NaN, and returns the appropriate NaN result. If either `a' or 590 1.1 bjh21 `b' is a signaling NaN, the invalid exception is raised. 591 1.1 bjh21 ------------------------------------------------------------------------------- 592 1.1 bjh21 */ 593 1.1 bjh21 static float128 propagateFloat128NaN( float128 a, float128 b ) 594 1.1 bjh21 { 595 1.1 bjh21 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 596 1.1 bjh21 597 1.1 bjh21 aIsNaN = float128_is_nan( a ); 598 1.1 bjh21 aIsSignalingNaN = float128_is_signaling_nan( a ); 599 1.1 bjh21 bIsNaN = float128_is_nan( b ); 600 1.1 bjh21 bIsSignalingNaN = float128_is_signaling_nan( b ); 601 1.1 bjh21 a.high |= LIT64( 0x0000800000000000 ); 602 1.1 bjh21 b.high |= LIT64( 0x0000800000000000 ); 603 1.1 bjh21 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 604 1.1 bjh21 if ( aIsNaN ) { 605 1.1 bjh21 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 606 1.1 bjh21 } 607 1.1 bjh21 else { 608 1.1 bjh21 return b; 609 1.1 bjh21 } 610 1.1 bjh21 611 1.1 bjh21 } 612 1.1 bjh21 613 1.1 bjh21 #endif 614 1.1 bjh21 615