1 /* Copyright (C) 2007, 2009 Free Software Foundation, Inc. 2 3 This file is part of GCC. 4 5 GCC is free software; you can redistribute it and/or modify it under 6 the terms of the GNU General Public License as published by the Free 7 Software Foundation; either version 3, or (at your option) any later 8 version. 9 10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 11 WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 for more details. 14 15 Under Section 7 of GPL version 3, you are granted additional 16 permissions described in the GCC Runtime Library Exception, version 17 3.1, as published by the Free Software Foundation. 18 19 You should have received a copy of the GNU General Public License and 20 a copy of the GCC Runtime Library Exception along with this program; 21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 22 <http://www.gnu.org/licenses/>. */ 23 24 #include "bid_internal.h" 25 26 static const UINT64 mult_factor[16] = { 27 1ull, 10ull, 100ull, 1000ull, 28 10000ull, 100000ull, 1000000ull, 10000000ull, 29 100000000ull, 1000000000ull, 10000000000ull, 100000000000ull, 30 1000000000000ull, 10000000000000ull, 31 100000000000000ull, 1000000000000000ull 32 }; 33 34 /***************************************************************************** 35 * BID64 non-computational functions: 36 * - bid64_isSigned 37 * - bid64_isNormal 38 * - bid64_isSubnormal 39 * - bid64_isFinite 40 * - bid64_isZero 41 * - bid64_isInf 42 * - bid64_isSignaling 43 * - bid64_isCanonical 44 * - bid64_isNaN 45 * - bid64_copy 46 * - bid64_negate 47 * - bid64_abs 48 * - bid64_copySign 49 * - bid64_class 50 * - bid64_sameQuantum 51 * - bid64_totalOrder 52 * - bid64_totalOrderMag 53 * - bid64_radix 54 ****************************************************************************/ 55 56 #if DECIMAL_CALL_BY_REFERENCE 57 void 58 bid64_isSigned (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 59 UINT64 x = *px; 60 #else 61 int 62 bid64_isSigned (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 63 #endif 64 int res; 65 66 res = ((x & MASK_SIGN) == MASK_SIGN); 67 BID_RETURN (res); 68 } 69 70 // return 1 iff x is not zero, nor NaN nor subnormal nor infinity 71 #if DECIMAL_CALL_BY_REFERENCE 72 void 73 bid64_isNormal (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 74 UINT64 x = *px; 75 #else 76 int 77 bid64_isNormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 78 #endif 79 int res; 80 UINT128 sig_x_prime; 81 UINT64 sig_x; 82 unsigned int exp_x; 83 84 if ((x & MASK_INF) == MASK_INF) { // x is either INF or NaN 85 res = 0; 86 } else { 87 // decode number into exponent and significand 88 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 89 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; 90 // check for zero or non-canonical 91 if (sig_x > 9999999999999999ull || sig_x == 0) { 92 res = 0; // zero or non-canonical 93 BID_RETURN (res); 94 } 95 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; 96 } else { 97 sig_x = (x & MASK_BINARY_SIG1); 98 if (sig_x == 0) { 99 res = 0; // zero 100 BID_RETURN (res); 101 } 102 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; 103 } 104 // if exponent is less than -383, the number may be subnormal 105 // if (exp_x - 398 = -383) the number may be subnormal 106 if (exp_x < 15) { 107 __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]); 108 if (sig_x_prime.w[1] == 0 109 && sig_x_prime.w[0] < 1000000000000000ull) { 110 res = 0; // subnormal 111 } else { 112 res = 1; // normal 113 } 114 } else { 115 res = 1; // normal 116 } 117 } 118 BID_RETURN (res); 119 } 120 121 // return 1 iff x is not zero, nor NaN nor normal nor infinity 122 #if DECIMAL_CALL_BY_REFERENCE 123 void 124 bid64_isSubnormal (int *pres, 125 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 126 UINT64 x = *px; 127 #else 128 int 129 bid64_isSubnormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 130 #endif 131 int res; 132 UINT128 sig_x_prime; 133 UINT64 sig_x; 134 unsigned int exp_x; 135 136 if ((x & MASK_INF) == MASK_INF) { // x is either INF or NaN 137 res = 0; 138 } else { 139 // decode number into exponent and significand 140 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 141 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; 142 // check for zero or non-canonical 143 if (sig_x > 9999999999999999ull || sig_x == 0) { 144 res = 0; // zero or non-canonical 145 BID_RETURN (res); 146 } 147 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; 148 } else { 149 sig_x = (x & MASK_BINARY_SIG1); 150 if (sig_x == 0) { 151 res = 0; // zero 152 BID_RETURN (res); 153 } 154 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; 155 } 156 // if exponent is less than -383, the number may be subnormal 157 // if (exp_x - 398 = -383) the number may be subnormal 158 if (exp_x < 15) { 159 __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]); 160 if (sig_x_prime.w[1] == 0 161 && sig_x_prime.w[0] < 1000000000000000ull) { 162 res = 1; // subnormal 163 } else { 164 res = 0; // normal 165 } 166 } else { 167 res = 0; // normal 168 } 169 } 170 BID_RETURN (res); 171 } 172 173 //iff x is zero, subnormal or normal (not infinity or NaN) 174 #if DECIMAL_CALL_BY_REFERENCE 175 void 176 bid64_isFinite (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 177 UINT64 x = *px; 178 #else 179 int 180 bid64_isFinite (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 181 #endif 182 int res; 183 184 res = ((x & MASK_INF) != MASK_INF); 185 BID_RETURN (res); 186 } 187 188 #if DECIMAL_CALL_BY_REFERENCE 189 void 190 bid64_isZero (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 191 UINT64 x = *px; 192 #else 193 int 194 bid64_isZero (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 195 #endif 196 int res; 197 198 // if infinity or nan, return 0 199 if ((x & MASK_INF) == MASK_INF) { 200 res = 0; 201 } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 202 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] 203 // => sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; 204 // if(sig_x > 9999999999999999ull) {return 1;} 205 res = 206 (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) > 207 9999999999999999ull); 208 } else { 209 res = ((x & MASK_BINARY_SIG1) == 0); 210 } 211 BID_RETURN (res); 212 } 213 214 #if DECIMAL_CALL_BY_REFERENCE 215 void 216 bid64_isInf (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 217 UINT64 x = *px; 218 #else 219 int 220 bid64_isInf (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 221 #endif 222 int res; 223 224 res = ((x & MASK_INF) == MASK_INF) && ((x & MASK_NAN) != MASK_NAN); 225 BID_RETURN (res); 226 } 227 228 #if DECIMAL_CALL_BY_REFERENCE 229 void 230 bid64_isSignaling (int *pres, 231 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 232 UINT64 x = *px; 233 #else 234 int 235 bid64_isSignaling (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 236 #endif 237 int res; 238 239 res = ((x & MASK_SNAN) == MASK_SNAN); 240 BID_RETURN (res); 241 } 242 243 #if DECIMAL_CALL_BY_REFERENCE 244 void 245 bid64_isCanonical (int *pres, 246 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 247 UINT64 x = *px; 248 #else 249 int 250 bid64_isCanonical (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 251 #endif 252 int res; 253 254 if ((x & MASK_NAN) == MASK_NAN) { // NaN 255 if (x & 0x01fc000000000000ull) { 256 res = 0; 257 } else if ((x & 0x0003ffffffffffffull) > 999999999999999ull) { // payload 258 res = 0; 259 } else { 260 res = 1; 261 } 262 } else if ((x & MASK_INF) == MASK_INF) { 263 if (x & 0x03ffffffffffffffull) { 264 res = 0; 265 } else { 266 res = 1; 267 } 268 } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // 54-bit coeff. 269 res = 270 (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) <= 271 9999999999999999ull); 272 } else { // 53-bit coeff. 273 res = 1; 274 } 275 BID_RETURN (res); 276 } 277 278 #if DECIMAL_CALL_BY_REFERENCE 279 void 280 bid64_isNaN (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 281 UINT64 x = *px; 282 #else 283 int 284 bid64_isNaN (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 285 #endif 286 int res; 287 288 res = ((x & MASK_NAN) == MASK_NAN); 289 BID_RETURN (res); 290 } 291 292 // copies a floating-point operand x to destination y, with no change 293 #if DECIMAL_CALL_BY_REFERENCE 294 void 295 bid64_copy (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 296 UINT64 x = *px; 297 #else 298 UINT64 299 bid64_copy (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 300 #endif 301 UINT64 res; 302 303 res = x; 304 BID_RETURN (res); 305 } 306 307 // copies a floating-point operand x to destination y, reversing the sign 308 #if DECIMAL_CALL_BY_REFERENCE 309 void 310 bid64_negate (UINT64 * pres, 311 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 312 UINT64 x = *px; 313 #else 314 UINT64 315 bid64_negate (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 316 #endif 317 UINT64 res; 318 319 res = x ^ MASK_SIGN; 320 BID_RETURN (res); 321 } 322 323 // copies a floating-point operand x to destination y, changing the sign to positive 324 #if DECIMAL_CALL_BY_REFERENCE 325 void 326 bid64_abs (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 327 UINT64 x = *px; 328 #else 329 UINT64 330 bid64_abs (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 331 #endif 332 UINT64 res; 333 334 res = x & ~MASK_SIGN; 335 BID_RETURN (res); 336 } 337 338 // copies operand x to destination in the same format as x, but 339 // with the sign of y 340 #if DECIMAL_CALL_BY_REFERENCE 341 void 342 bid64_copySign (UINT64 * pres, UINT64 * px, 343 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 344 UINT64 x = *px; 345 UINT64 y = *py; 346 #else 347 UINT64 348 bid64_copySign (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 349 #endif 350 UINT64 res; 351 352 res = (x & ~MASK_SIGN) | (y & MASK_SIGN); 353 BID_RETURN (res); 354 } 355 356 #if DECIMAL_CALL_BY_REFERENCE 357 void 358 bid64_class (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 359 UINT64 x = *px; 360 #else 361 int 362 bid64_class (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 363 #endif 364 int res; 365 UINT128 sig_x_prime; 366 UINT64 sig_x; 367 int exp_x; 368 369 if ((x & MASK_NAN) == MASK_NAN) { 370 // is the NaN signaling? 371 if ((x & MASK_SNAN) == MASK_SNAN) { 372 res = signalingNaN; 373 BID_RETURN (res); 374 } 375 // if NaN and not signaling, must be quietNaN 376 res = quietNaN; 377 BID_RETURN (res); 378 } else if ((x & MASK_INF) == MASK_INF) { 379 // is the Infinity negative? 380 if ((x & MASK_SIGN) == MASK_SIGN) { 381 res = negativeInfinity; 382 } else { 383 // otherwise, must be positive infinity 384 res = positiveInfinity; 385 } 386 BID_RETURN (res); 387 } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 388 // decode number into exponent and significand 389 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; 390 // check for zero or non-canonical 391 if (sig_x > 9999999999999999ull || sig_x == 0) { 392 if ((x & MASK_SIGN) == MASK_SIGN) { 393 res = negativeZero; 394 } else { 395 res = positiveZero; 396 } 397 BID_RETURN (res); 398 } 399 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; 400 } else { 401 sig_x = (x & MASK_BINARY_SIG1); 402 if (sig_x == 0) { 403 res = 404 ((x & MASK_SIGN) == MASK_SIGN) ? negativeZero : positiveZero; 405 BID_RETURN (res); 406 } 407 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; 408 } 409 // if exponent is less than -383, number may be subnormal 410 // if (exp_x - 398 < -383) 411 if (exp_x < 15) { // sig_x *10^exp_x 412 __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]); 413 if (sig_x_prime.w[1] == 0 414 && (sig_x_prime.w[0] < 1000000000000000ull)) { 415 res = 416 ((x & MASK_SIGN) == 417 MASK_SIGN) ? negativeSubnormal : positiveSubnormal; 418 BID_RETURN (res); 419 } 420 } 421 // otherwise, normal number, determine the sign 422 res = 423 ((x & MASK_SIGN) == MASK_SIGN) ? negativeNormal : positiveNormal; 424 BID_RETURN (res); 425 } 426 427 // true if the exponents of x and y are the same, false otherwise. 428 // The special cases of sameQuantum (NaN, NaN) and sameQuantum (Inf, Inf) are 429 // true. 430 // If exactly one operand is infinite or exactly one operand is NaN, then false 431 #if DECIMAL_CALL_BY_REFERENCE 432 void 433 bid64_sameQuantum (int *pres, UINT64 * px, 434 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 435 UINT64 x = *px; 436 UINT64 y = *py; 437 #else 438 int 439 bid64_sameQuantum (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 440 #endif 441 int res; 442 unsigned int exp_x, exp_y; 443 444 // if both operands are NaN, return true; if just one is NaN, return false 445 if ((x & MASK_NAN) == MASK_NAN || ((y & MASK_NAN) == MASK_NAN)) { 446 res = ((x & MASK_NAN) == MASK_NAN && (y & MASK_NAN) == MASK_NAN); 447 BID_RETURN (res); 448 } 449 // if both operands are INF, return true; if just one is INF, return false 450 if ((x & MASK_INF) == MASK_INF || (y & MASK_INF) == MASK_INF) { 451 res = ((x & MASK_INF) == MASK_INF && (y & MASK_INF) == MASK_INF); 452 BID_RETURN (res); 453 } 454 // decode exponents for both numbers, and return true if they match 455 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 456 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; 457 } else { 458 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; 459 } 460 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 461 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; 462 } else { 463 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; 464 } 465 res = (exp_x == exp_y); 466 BID_RETURN (res); 467 } 468 469 #if DECIMAL_CALL_BY_REFERENCE 470 void 471 bid64_totalOrder (int *pres, UINT64 * px, 472 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 473 UINT64 x = *px; 474 UINT64 y = *py; 475 #else 476 int 477 bid64_totalOrder (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 478 #endif 479 int res; 480 int exp_x, exp_y; 481 UINT64 sig_x, sig_y, pyld_y, pyld_x; 482 UINT128 sig_n_prime; 483 char x_is_zero = 0, y_is_zero = 0; 484 485 // NaN (CASE1) 486 // if x and y are unordered numerically because either operand is NaN 487 // (1) totalOrder(-NaN, number) is true 488 // (2) totalOrder(number, +NaN) is true 489 // (3) if x and y are both NaN: 490 // i) negative sign bit < positive sign bit 491 // ii) signaling < quiet for +NaN, reverse for -NaN 492 // iii) lesser payload < greater payload for +NaN (reverse for -NaN) 493 // iv) else if bitwise identical (in canonical form), return 1 494 if ((x & MASK_NAN) == MASK_NAN) { 495 // if x is -NaN 496 if ((x & MASK_SIGN) == MASK_SIGN) { 497 // return true, unless y is -NaN also 498 if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) != MASK_SIGN) { 499 res = 1; // y is a number, return 1 500 BID_RETURN (res); 501 } else { // if y and x are both -NaN 502 // if x and y are both -sNaN or both -qNaN, we have to compare payloads 503 // this xnor statement evaluates to true if both are sNaN or qNaN 504 if (! 505 (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) == 506 MASK_SNAN))) { 507 // it comes down to the payload. we want to return true if x has a 508 // larger payload, or if the payloads are equal (canonical forms 509 // are bitwise identical) 510 pyld_y = y & 0x0003ffffffffffffull; 511 pyld_x = x & 0x0003ffffffffffffull; 512 if (pyld_y > 999999999999999ull || pyld_y == 0) { 513 // if y is zero, x must be less than or numerically equal 514 // y's payload is 0 515 res = 1; 516 BID_RETURN (res); 517 } 518 // if x is zero and y isn't, x has the smaller payload 519 // definitely (since we know y isn't 0 at this point) 520 if (pyld_x > 999999999999999ull || pyld_x == 0) { 521 // x's payload is 0 522 res = 0; 523 BID_RETURN (res); 524 } 525 res = (pyld_x >= pyld_y); 526 BID_RETURN (res); 527 } else { 528 // either x = -sNaN and y = -qNaN or x = -qNaN and y = -sNaN 529 res = (y & MASK_SNAN) == MASK_SNAN; // totalOrder(-qNaN, -sNaN) == 1 530 BID_RETURN (res); 531 } 532 } 533 } else { // x is +NaN 534 // return false, unless y is +NaN also 535 if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) == MASK_SIGN) { 536 res = 0; // y is a number, return 1 537 BID_RETURN (res); 538 } else { 539 // x and y are both +NaN; 540 // must investigate payload if both quiet or both signaling 541 // this xnor statement will be true if both x and y are +qNaN or +sNaN 542 if (! 543 (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) == 544 MASK_SNAN))) { 545 // it comes down to the payload. we want to return true if x has a 546 // smaller payload, or if the payloads are equal (canonical forms 547 // are bitwise identical) 548 pyld_y = y & 0x0003ffffffffffffull; 549 pyld_x = x & 0x0003ffffffffffffull; 550 // if x is zero and y isn't, x has the smaller 551 // payload definitely (since we know y isn't 0 at this point) 552 if (pyld_x > 999999999999999ull || pyld_x == 0) { 553 res = 1; 554 BID_RETURN (res); 555 } 556 if (pyld_y > 999999999999999ull || pyld_y == 0) { 557 // if y is zero, x must be less than or numerically equal 558 res = 0; 559 BID_RETURN (res); 560 } 561 res = (pyld_x <= pyld_y); 562 BID_RETURN (res); 563 } else { 564 // return true if y is +qNaN and x is +sNaN 565 // (we know they're different bc of xor if_stmt above) 566 res = ((x & MASK_SNAN) == MASK_SNAN); 567 BID_RETURN (res); 568 } 569 } 570 } 571 } else if ((y & MASK_NAN) == MASK_NAN) { 572 // x is certainly not NAN in this case. 573 // return true if y is positive 574 res = ((y & MASK_SIGN) != MASK_SIGN); 575 BID_RETURN (res); 576 } 577 // SIMPLE (CASE2) 578 // if all the bits are the same, these numbers are equal. 579 if (x == y) { 580 res = 1; 581 BID_RETURN (res); 582 } 583 // OPPOSITE SIGNS (CASE 3) 584 // if signs are opposite, return 1 if x is negative 585 // (if x<y, totalOrder is true) 586 if (((x & MASK_SIGN) == MASK_SIGN) ^ ((y & MASK_SIGN) == MASK_SIGN)) { 587 res = (x & MASK_SIGN) == MASK_SIGN; 588 BID_RETURN (res); 589 } 590 // INFINITY (CASE4) 591 if ((x & MASK_INF) == MASK_INF) { 592 // if x==neg_inf, return (y == neg_inf)?1:0; 593 if ((x & MASK_SIGN) == MASK_SIGN) { 594 res = 1; 595 BID_RETURN (res); 596 } else { 597 // x is positive infinity, only return1 if y 598 // is positive infinity as well 599 // (we know y has same sign as x) 600 res = ((y & MASK_INF) == MASK_INF); 601 BID_RETURN (res); 602 } 603 } else if ((y & MASK_INF) == MASK_INF) { 604 // x is finite, so: 605 // if y is +inf, x<y 606 // if y is -inf, x>y 607 res = ((y & MASK_SIGN) != MASK_SIGN); 608 BID_RETURN (res); 609 } 610 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => 611 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 612 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; 613 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; 614 if (sig_x > 9999999999999999ull || sig_x == 0) { 615 x_is_zero = 1; 616 } 617 } else { 618 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; 619 sig_x = (x & MASK_BINARY_SIG1); 620 if (sig_x == 0) { 621 x_is_zero = 1; 622 } 623 } 624 625 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] => 626 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 627 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; 628 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; 629 if (sig_y > 9999999999999999ull || sig_y == 0) { 630 y_is_zero = 1; 631 } 632 } else { 633 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; 634 sig_y = (y & MASK_BINARY_SIG1); 635 if (sig_y == 0) { 636 y_is_zero = 1; 637 } 638 } 639 640 // ZERO (CASE 5) 641 // if x and y represent the same entities, and 642 // both are negative , return true iff exp_x <= exp_y 643 if (x_is_zero && y_is_zero) { 644 if (!((x & MASK_SIGN) == MASK_SIGN) ^ 645 ((y & MASK_SIGN) == MASK_SIGN)) { 646 // if signs are the same: 647 // totalOrder(x,y) iff exp_x >= exp_y for negative numbers 648 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers 649 if (exp_x == exp_y) { 650 res = 1; 651 BID_RETURN (res); 652 } 653 res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN); 654 BID_RETURN (res); 655 } else { 656 // signs are different. 657 // totalOrder(-0, +0) is true 658 // totalOrder(+0, -0) is false 659 res = ((x & MASK_SIGN) == MASK_SIGN); 660 BID_RETURN (res); 661 } 662 } 663 // if x is zero and y isn't, clearly x has the smaller payload. 664 if (x_is_zero) { 665 res = ((y & MASK_SIGN) != MASK_SIGN); 666 BID_RETURN (res); 667 } 668 // if y is zero, and x isn't, clearly y has the smaller payload. 669 if (y_is_zero) { 670 res = ((x & MASK_SIGN) == MASK_SIGN); 671 BID_RETURN (res); 672 } 673 // REDUNDANT REPRESENTATIONS (CASE6) 674 // if both components are either bigger or smaller, 675 // it is clear what needs to be done 676 if (sig_x > sig_y && exp_x >= exp_y) { 677 res = ((x & MASK_SIGN) == MASK_SIGN); 678 BID_RETURN (res); 679 } 680 if (sig_x < sig_y && exp_x <= exp_y) { 681 res = ((x & MASK_SIGN) != MASK_SIGN); 682 BID_RETURN (res); 683 } 684 // if exp_x is 15 greater than exp_y, it is 685 // definitely larger, so no need for compensation 686 if (exp_x - exp_y > 15) { 687 // difference cannot be greater than 10^15 688 res = ((x & MASK_SIGN) == MASK_SIGN); 689 BID_RETURN (res); 690 } 691 // if exp_x is 15 less than exp_y, it is 692 // definitely smaller, no need for compensation 693 if (exp_y - exp_x > 15) { 694 res = ((x & MASK_SIGN) != MASK_SIGN); 695 BID_RETURN (res); 696 } 697 // if |exp_x - exp_y| < 15, it comes down 698 // to the compensated significand 699 if (exp_x > exp_y) { 700 // otherwise adjust the x significand upwards 701 __mul_64x64_to_128MACH (sig_n_prime, sig_x, 702 mult_factor[exp_x - exp_y]); 703 // if x and y represent the same entities, 704 // and both are negative, return true iff exp_x <= exp_y 705 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { 706 // case cannot occure, because all bits must 707 // be the same - would have been caught if (x==y) 708 res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN); 709 BID_RETURN (res); 710 } 711 // if positive, return 1 if adjusted x is smaller than y 712 res = ((sig_n_prime.w[1] == 0) 713 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) == 714 MASK_SIGN); 715 BID_RETURN (res); 716 } 717 // adjust the y significand upwards 718 __mul_64x64_to_128MACH (sig_n_prime, sig_y, 719 mult_factor[exp_y - exp_x]); 720 721 // if x and y represent the same entities, 722 // and both are negative, return true iff exp_x <= exp_y 723 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { 724 // Cannot occur, because all bits must be the same. 725 // Case would have been caught if (x==y) 726 res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN); 727 BID_RETURN (res); 728 } 729 // values are not equal, for positive numbers return 1 730 // if x is less than y. 0 otherwise 731 res = ((sig_n_prime.w[1] > 0) 732 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) == 733 MASK_SIGN); 734 BID_RETURN (res); 735 } 736 737 // totalOrderMag is TotalOrder(abs(x), abs(y)) 738 #if DECIMAL_CALL_BY_REFERENCE 739 void 740 bid64_totalOrderMag (int *pres, UINT64 * px, 741 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 742 UINT64 x = *px; 743 UINT64 y = *py; 744 #else 745 int 746 bid64_totalOrderMag (UINT64 x, 747 UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 748 #endif 749 int res; 750 int exp_x, exp_y; 751 UINT64 sig_x, sig_y, pyld_y, pyld_x; 752 UINT128 sig_n_prime; 753 char x_is_zero = 0, y_is_zero = 0; 754 755 // NaN (CASE 1) 756 // if x and y are unordered numerically because either operand is NaN 757 // (1) totalOrder(number, +NaN) is true 758 // (2) if x and y are both NaN: 759 // i) signaling < quiet for +NaN 760 // ii) lesser payload < greater payload for +NaN 761 // iii) else if bitwise identical (in canonical form), return 1 762 if ((x & MASK_NAN) == MASK_NAN) { 763 // x is +NaN 764 765 // return false, unless y is +NaN also 766 if ((y & MASK_NAN) != MASK_NAN) { 767 res = 0; // y is a number, return 1 768 BID_RETURN (res); 769 770 } else { 771 772 // x and y are both +NaN; 773 // must investigate payload if both quiet or both signaling 774 // this xnor statement will be true if both x and y are +qNaN or +sNaN 775 if (! 776 (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) == 777 MASK_SNAN))) { 778 // it comes down to the payload. we want to return true if x has a 779 // smaller payload, or if the payloads are equal (canonical forms 780 // are bitwise identical) 781 pyld_y = y & 0x0003ffffffffffffull; 782 pyld_x = x & 0x0003ffffffffffffull; 783 // if x is zero and y isn't, x has the smaller 784 // payload definitely (since we know y isn't 0 at this point) 785 if (pyld_x > 999999999999999ull || pyld_x == 0) { 786 res = 1; 787 BID_RETURN (res); 788 } 789 790 if (pyld_y > 999999999999999ull || pyld_y == 0) { 791 // if y is zero, x must be less than or numerically equal 792 res = 0; 793 BID_RETURN (res); 794 } 795 res = (pyld_x <= pyld_y); 796 BID_RETURN (res); 797 798 } else { 799 // return true if y is +qNaN and x is +sNaN 800 // (we know they're different bc of xor if_stmt above) 801 res = ((x & MASK_SNAN) == MASK_SNAN); 802 BID_RETURN (res); 803 } 804 } 805 806 } else if ((y & MASK_NAN) == MASK_NAN) { 807 // x is certainly not NAN in this case. 808 // return true if y is positive 809 res = 1; 810 BID_RETURN (res); 811 } 812 // SIMPLE (CASE2) 813 // if all the bits (except sign bit) are the same, 814 // these numbers are equal. 815 if ((x & ~MASK_SIGN) == (y & ~MASK_SIGN)) { 816 res = 1; 817 BID_RETURN (res); 818 } 819 // INFINITY (CASE3) 820 if ((x & MASK_INF) == MASK_INF) { 821 // x is positive infinity, only return1 822 // if y is positive infinity as well 823 res = ((y & MASK_INF) == MASK_INF); 824 BID_RETURN (res); 825 } else if ((y & MASK_INF) == MASK_INF) { 826 // x is finite, so: 827 // if y is +inf, x<y 828 res = 1; 829 BID_RETURN (res); 830 } 831 // if steering bits are 11 (condition will be 0), 832 // then exponent is G[0:w+1] => 833 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 834 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51; 835 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; 836 if (sig_x > 9999999999999999ull || sig_x == 0) { 837 x_is_zero = 1; 838 } 839 } else { 840 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53; 841 sig_x = (x & MASK_BINARY_SIG1); 842 if (sig_x == 0) { 843 x_is_zero = 1; 844 } 845 } 846 847 // if steering bits are 11 (condition will be 0), 848 // then exponent is G[0:w+1] => 849 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) { 850 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51; 851 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2; 852 if (sig_y > 9999999999999999ull || sig_y == 0) { 853 y_is_zero = 1; 854 } 855 } else { 856 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53; 857 sig_y = (y & MASK_BINARY_SIG1); 858 if (sig_y == 0) { 859 y_is_zero = 1; 860 } 861 } 862 863 // ZERO (CASE 5) 864 // if x and y represent the same entities, 865 // and both are negative , return true iff exp_x <= exp_y 866 if (x_is_zero && y_is_zero) { 867 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers 868 res = (exp_x <= exp_y); 869 BID_RETURN (res); 870 } 871 // if x is zero and y isn't, clearly x has the smaller payload. 872 if (x_is_zero) { 873 res = 1; 874 BID_RETURN (res); 875 } 876 // if y is zero, and x isn't, clearly y has the smaller payload. 877 if (y_is_zero) { 878 res = 0; 879 BID_RETURN (res); 880 } 881 // REDUNDANT REPRESENTATIONS (CASE6) 882 // if both components are either bigger or smaller 883 if (sig_x > sig_y && exp_x >= exp_y) { 884 res = 0; 885 BID_RETURN (res); 886 } 887 if (sig_x < sig_y && exp_x <= exp_y) { 888 res = 1; 889 BID_RETURN (res); 890 } 891 // if exp_x is 15 greater than exp_y, it is definitely 892 // larger, so no need for compensation 893 if (exp_x - exp_y > 15) { 894 res = 0; // difference cannot be greater than 10^15 895 BID_RETURN (res); 896 } 897 // if exp_x is 15 less than exp_y, it is definitely 898 // smaller, no need for compensation 899 if (exp_y - exp_x > 15) { 900 res = 1; 901 BID_RETURN (res); 902 } 903 // if |exp_x - exp_y| < 15, it comes down 904 // to the compensated significand 905 if (exp_x > exp_y) { 906 907 // otherwise adjust the x significand upwards 908 __mul_64x64_to_128MACH (sig_n_prime, sig_x, 909 mult_factor[exp_x - exp_y]); 910 911 // if x and y represent the same entities, 912 // and both are negative, return true iff exp_x <= exp_y 913 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) { 914 // case cannot occur, because all bits 915 // must be the same - would have been caught if (x==y) 916 res = (exp_x <= exp_y); 917 BID_RETURN (res); 918 } 919 // if positive, return 1 if adjusted x is smaller than y 920 res = ((sig_n_prime.w[1] == 0) && sig_n_prime.w[0] < sig_y); 921 BID_RETURN (res); 922 } 923 // adjust the y significand upwards 924 __mul_64x64_to_128MACH (sig_n_prime, sig_y, 925 mult_factor[exp_y - exp_x]); 926 927 // if x and y represent the same entities, 928 // and both are negative, return true iff exp_x <= exp_y 929 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) { 930 res = (exp_x <= exp_y); 931 BID_RETURN (res); 932 } 933 // values are not equal, for positive numbers 934 // return 1 if x is less than y. 0 otherwise 935 res = ((sig_n_prime.w[1] > 0) || (sig_x < sig_n_prime.w[0])); 936 BID_RETURN (res); 937 938 } 939 940 #if DECIMAL_CALL_BY_REFERENCE 941 void 942 bid64_radix (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 943 UINT64 x = *px; 944 #else 945 int 946 bid64_radix (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 947 #endif 948 int res; 949 if (x) // dummy test 950 res = 10; 951 else 952 res = 10; 953 BID_RETURN (res); 954 } 955