1 /* Copyright (C) 2007-2020 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 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_equal, x, y) 27 28 int res; 29 int exp_x, exp_y, exp_t; 30 UINT128 sig_x, sig_y, sig_t; 31 UINT192 sig_n_prime192; 32 UINT256 sig_n_prime256; 33 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 34 35 // NaN (CASE1) 36 // if either number is NAN, the comparison is unordered, 37 // rather than equal : return 0 38 if (((x.w[1] & MASK_NAN) == MASK_NAN) 39 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 40 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 41 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 42 *pfpsf |= INVALID_EXCEPTION; 43 } 44 { 45 res = 0; 46 BID_RETURN (res); 47 } 48 } 49 // SIMPLE (CASE2) 50 // if all the bits are the same, these numbers are equivalent. 51 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 52 res = 1; 53 BID_RETURN (res); 54 } 55 // INFINITY (CASE3) 56 if ((x.w[1] & MASK_INF) == MASK_INF) { 57 if ((y.w[1] & MASK_INF) == MASK_INF) { 58 res = (((x.w[1] ^ y.w[1]) & MASK_SIGN) != MASK_SIGN); 59 BID_RETURN (res); 60 } else { 61 res = 0; 62 BID_RETURN (res); 63 } 64 } 65 if ((y.w[1] & MASK_INF) == MASK_INF) { 66 res = 0; 67 BID_RETURN (res); 68 } 69 // CONVERT X 70 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 71 sig_x.w[0] = x.w[0]; 72 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 73 74 // CHECK IF X IS CANONICAL 75 // 9999999999999999999999999999999999(decimal) = 76 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 77 // [0, 10^34) is the 754r supported canonical range. 78 // If the value exceeds that, it is interpreted as 0. 79 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 80 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 81 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 82 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 83 non_canon_x = 1; 84 else 85 non_canon_x = 0; 86 87 // CONVERT Y 88 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 89 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 90 sig_y.w[0] = y.w[0]; 91 92 // CHECK IF Y IS CANONICAL 93 // 9999999999999999999999999999999999(decimal) = 94 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 95 // [0, 10^34) is the 754r supported canonical range. 96 // If the value exceeds that, it is interpreted as 0. 97 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 98 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 99 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 100 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 101 non_canon_y = 1; 102 else 103 non_canon_y = 0; 104 105 // some properties: 106 // (+ZERO == -ZERO) => therefore ignore the sign 107 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 108 // ignore the exponent field 109 // (Any non-canonical # is considered 0) 110 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 111 x_is_zero = 1; 112 } 113 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 114 y_is_zero = 1; 115 } 116 117 if (x_is_zero && y_is_zero) { 118 res = 1; 119 BID_RETURN (res); 120 } else if ((x_is_zero && !y_is_zero) || (!x_is_zero && y_is_zero)) { 121 res = 0; 122 BID_RETURN (res); 123 } 124 // OPPOSITE SIGN (CASE5) 125 // now, if the sign bits differ => not equal : return 0 126 if ((x.w[1] ^ y.w[1]) & MASK_SIGN) { 127 res = 0; 128 BID_RETURN (res); 129 } 130 // REDUNDANT REPRESENTATIONS (CASE6) 131 if (exp_x > exp_y) { // to simplify the loop below, 132 SWAP (exp_x, exp_y, exp_t); // put the larger exp in y, 133 SWAP (sig_x.w[1], sig_y.w[1], sig_t.w[1]); // and the smaller exp in x 134 SWAP (sig_x.w[0], sig_y.w[0], sig_t.w[0]); // and the smaller exp in x 135 } 136 137 138 if (exp_y - exp_x > 33) { 139 res = 0; 140 BID_RETURN (res); 141 } // difference cannot be greater than 10^33 142 143 if (exp_y - exp_x > 19) { 144 // recalculate y's significand upwards 145 __mul_128x128_to_256 (sig_n_prime256, sig_y, 146 ten2k128[exp_y - exp_x - 20]); 147 { 148 res = ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0) 149 && (sig_n_prime256.w[1] == sig_x.w[1]) 150 && (sig_n_prime256.w[0] == sig_x.w[0])); 151 BID_RETURN (res); 152 } 153 154 } 155 //else{ 156 // recalculate y's significand upwards 157 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y); 158 { 159 res = ((sig_n_prime192.w[2] == 0) 160 && (sig_n_prime192.w[1] == sig_x.w[1]) 161 && (sig_n_prime192.w[0] == sig_x.w[0])); 162 BID_RETURN (res); 163 } 164 } 165 166 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_greater, x, 167 y) 168 169 int res; 170 int exp_x, exp_y; 171 int diff; 172 UINT128 sig_x, sig_y; 173 UINT192 sig_n_prime192; 174 UINT256 sig_n_prime256; 175 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 176 177 // NaN (CASE1) 178 // if either number is NAN, the comparison is unordered, rather than 179 // equal : return 0 180 if (((x.w[1] & MASK_NAN) == MASK_NAN) 181 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 182 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 183 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 184 *pfpsf |= INVALID_EXCEPTION; 185 } 186 { 187 res = 0; 188 BID_RETURN (res); 189 } 190 } 191 // SIMPLE (CASE2) 192 // if all the bits are the same, these numbers are equal (not Greater). 193 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 194 res = 0; 195 BID_RETURN (res); 196 } 197 // INFINITY (CASE3) 198 if ((x.w[1] & MASK_INF) == MASK_INF) { 199 // if x is neg infinity, there is no way it is greater than y, return 0 200 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) { 201 res = 0; 202 BID_RETURN (res); 203 } 204 // x is pos infinity, it is greater, unless y is positive infinity => 205 // return y!=pos_infinity 206 else { 207 res = (((y.w[1] & MASK_INF) != MASK_INF) 208 || ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 209 BID_RETURN (res); 210 } 211 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 212 // x is finite, so if y is positive infinity, then x is less, return 0 213 // if y is negative infinity, then x is greater, return 1 214 { 215 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 216 BID_RETURN (res); 217 } 218 } 219 // CONVERT X 220 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 221 sig_x.w[0] = x.w[0]; 222 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 223 224 // CHECK IF X IS CANONICAL 225 // 9999999999999999999999999999999999(decimal) = 226 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 227 // [0, 10^34) is the 754r supported canonical range. 228 // If the value exceeds that, it is interpreted as 0. 229 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 230 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 231 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 232 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 233 non_canon_x = 1; 234 else 235 non_canon_x = 0; 236 237 // CONVERT Y 238 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 239 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 240 sig_y.w[0] = y.w[0]; 241 242 // CHECK IF Y IS CANONICAL 243 // 9999999999999999999999999999999999(decimal) = 244 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 245 // [0, 10^34) is the 754r supported canonical range. 246 // If the value exceeds that, it is interpreted as 0. 247 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 248 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 249 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 250 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 251 non_canon_y = 1; 252 else 253 non_canon_y = 0; 254 255 // ZERO (CASE4) 256 // some properties: 257 // (+ZERO == -ZERO) => therefore ignore the sign 258 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 259 // ignore the exponent field 260 // (Any non-canonical # is considered 0) 261 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 262 x_is_zero = 1; 263 } 264 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 265 y_is_zero = 1; 266 } 267 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 268 if (x_is_zero && y_is_zero) { 269 res = 0; 270 BID_RETURN (res); 271 } 272 // is x is zero, it is greater if Y is negative 273 else if (x_is_zero) { 274 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 275 BID_RETURN (res); 276 } 277 // is y is zero, X is greater if it is positive 278 else if (y_is_zero) { 279 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 280 BID_RETURN (res); 281 } 282 // OPPOSITE SIGN (CASE5) 283 // now, if the sign bits differ, x is greater if y is negative 284 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 285 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 286 BID_RETURN (res); 287 } 288 // REDUNDANT REPRESENTATIONS (CASE6) 289 // if exponents are the same, then we have a simple comparison 290 // of the significands 291 if (exp_y == exp_x) { 292 res = (((sig_x.w[1] > sig_y.w[1]) 293 || (sig_x.w[1] == sig_y.w[1] 294 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) == 295 MASK_SIGN)); 296 BID_RETURN (res); 297 } 298 // if both components are either bigger or smaller, 299 // it is clear what needs to be done 300 if ((sig_x.w[1] > sig_y.w[1] 301 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 302 && exp_x >= exp_y) { 303 { 304 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 305 BID_RETURN (res); 306 } 307 } 308 if ((sig_x.w[1] < sig_y.w[1] 309 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 310 && exp_x <= exp_y) { 311 { 312 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 313 BID_RETURN (res); 314 } 315 } 316 317 diff = exp_x - exp_y; 318 319 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 320 if (diff > 0) { // to simplify the loop below, 321 322 // if exp_x is 33 greater than exp_y, no need for compensation 323 if (diff > 33) { 324 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 325 BID_RETURN (res); 326 } // difference cannot be greater than 10^33 327 328 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 329 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 330 331 // if postitive, return whichever significand is larger 332 // (converse if negative) 333 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 334 && sig_n_prime256.w[1] == sig_y.w[1] 335 && (sig_n_prime256.w[0] == sig_y.w[0])) { 336 res = 0; 337 BID_RETURN (res); 338 } // if equal, return 0 339 { 340 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 341 || (sig_n_prime256.w[1] > sig_y.w[1]) 342 || (sig_n_prime256.w[1] == sig_y.w[1] 343 && sig_n_prime256.w[0] > 344 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 345 BID_RETURN (res); 346 } 347 } 348 //else { //128 by 64 bit multiply -> 192 bits 349 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x); 350 351 // if postitive, return whichever significand is larger 352 // (converse if negative) 353 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 354 && (sig_n_prime192.w[0] == sig_y.w[0])) { 355 res = 0; 356 BID_RETURN (res); 357 } // if equal, return 0 358 { 359 res = (((sig_n_prime192.w[2] > 0) || 360 (sig_n_prime192.w[1] > sig_y.w[1]) || 361 (sig_n_prime192.w[1] == sig_y.w[1] && 362 sig_n_prime192.w[0] > sig_y.w[0])) ^ 363 ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 364 BID_RETURN (res); 365 } 366 } 367 368 diff = exp_y - exp_x; 369 370 // if exp_x is 33 less than exp_y, no need for compensation 371 if (diff > 33) { 372 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 373 BID_RETURN (res); 374 } 375 376 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 377 // adjust the y significand upwards 378 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 379 380 // if postitive, return whichever significand is larger 381 // (converse if negative) 382 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 383 && sig_n_prime256.w[1] == sig_x.w[1] 384 && (sig_n_prime256.w[0] == sig_x.w[0])) { 385 res = 0; 386 BID_RETURN (res); 387 } // if equal, return 0 388 { 389 res = ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 || 390 (sig_n_prime256.w[1] > sig_x.w[1] || 391 (sig_n_prime256.w[1] == sig_x.w[1] && 392 sig_n_prime256.w[0] > sig_x.w[0]))) ^ 393 ((x.w[1] & MASK_SIGN) != MASK_SIGN)); 394 BID_RETURN (res); 395 } 396 } 397 //else { //128 by 64 bit multiply -> 192 bits 398 // adjust the y significand upwards 399 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y); 400 401 // if postitive, return whichever significand is larger 402 // (converse if negative) 403 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 404 && (sig_n_prime192.w[0] == sig_x.w[0])) { 405 res = 0; 406 BID_RETURN (res); 407 } // if equal, return 0 408 { 409 res = (sig_n_prime192.w[2] != 0 410 || (sig_n_prime192.w[1] > sig_x.w[1] 411 || (sig_n_prime192.w[1] == sig_x.w[1] 412 && sig_n_prime192.w[0] > 413 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN); 414 BID_RETURN (res); 415 } 416 } 417 418 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, 419 bid128_quiet_greater_equal, x, 420 y) 421 422 int res; 423 int exp_x, exp_y; 424 int diff; 425 UINT128 sig_x, sig_y; 426 UINT192 sig_n_prime192; 427 UINT256 sig_n_prime256; 428 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 429 430 // NaN (CASE1) 431 // if either number is NAN, the comparison is unordered, 432 // rather than equal : return 1 433 if (((x.w[1] & MASK_NAN) == MASK_NAN) 434 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 435 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 436 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 437 *pfpsf |= INVALID_EXCEPTION; 438 } 439 { 440 res = 0; 441 BID_RETURN (res); 442 } 443 } 444 // SIMPLE (CASE2) 445 // if all the bits are the same, these numbers are equal (not Greater). 446 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 447 res = 1; 448 BID_RETURN (res); 449 } 450 // INFINITY (CASE3) 451 if ((x.w[1] & MASK_INF) == MASK_INF) { 452 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } 453 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) 454 // x is -inf, so it is less than y unless y is -inf 455 { 456 res = (((y.w[1] & MASK_INF) == MASK_INF) 457 && (y.w[1] & MASK_SIGN) == MASK_SIGN); 458 BID_RETURN (res); 459 } else 460 // x is pos_inf, no way for it to be less than y 461 { 462 res = 1; 463 BID_RETURN (res); 464 } 465 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 466 // x is finite, so if y is positive infinity, then x is less, return 0 467 // if y is negative infinity, then x is greater, return 1 468 { 469 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 470 BID_RETURN (res); 471 } 472 } 473 // CONVERT X 474 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 475 sig_x.w[0] = x.w[0]; 476 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 477 478 // CHECK IF X IS CANONICAL 479 // 9999999999999999999999999999999999(decimal) = 480 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 481 // [0, 10^34) is the 754r supported canonical range. 482 // If the value exceeds that, it is interpreted as 0. 483 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 484 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 485 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 486 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 487 non_canon_x = 1; 488 else 489 non_canon_x = 0; 490 491 // CONVERT Y 492 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 493 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 494 sig_y.w[0] = y.w[0]; 495 496 // CHECK IF Y IS CANONICAL 497 // 9999999999999999999999999999999999(decimal) = 498 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 499 // [0, 10^34) is the 754r supported canonical range. 500 // If the value exceeds that, it is interpreted as 0. 501 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 502 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 503 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 504 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 505 non_canon_y = 1; 506 else 507 non_canon_y = 0; 508 509 // ZERO (CASE4) 510 // some properties: 511 // (+ZERO == -ZERO) => therefore ignore the sign 512 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 513 // ignore the exponent field 514 // (Any non-canonical # is considered 0) 515 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 516 x_is_zero = 1; 517 } 518 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 519 y_is_zero = 1; 520 } 521 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 522 if (x_is_zero && y_is_zero) { 523 res = 1; 524 BID_RETURN (res); 525 } 526 // is x is zero, it is greater if Y is negative 527 else if (x_is_zero) { 528 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 529 BID_RETURN (res); 530 } 531 // is y is zero, X is greater if it is positive 532 else if (y_is_zero) { 533 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 534 BID_RETURN (res); 535 } 536 // OPPOSITE SIGN (CASE5) 537 // now, if the sign bits differ, x is greater if y is negative 538 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 539 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 540 BID_RETURN (res); 541 } 542 // REDUNDANT REPRESENTATIONS (CASE6) 543 // if exponents are the same, then we have a simple comparison of the 544 // significands 545 if (exp_y == exp_x) { 546 res = (((sig_x.w[1] > sig_y.w[1]) 547 || (sig_x.w[1] == sig_y.w[1] 548 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) == 549 MASK_SIGN)); 550 BID_RETURN (res); 551 } 552 // if both components are either bigger or smaller, 553 // it is clear what needs to be done 554 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0] 555 && exp_x > exp_y) { 556 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 557 BID_RETURN (res); 558 } 559 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0] 560 && exp_x < exp_y) { 561 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 562 BID_RETURN (res); 563 } 564 565 diff = exp_x - exp_y; 566 567 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 568 if (diff > 0) { // to simplify the loop below, 569 570 // if exp_x is 33 greater than exp_y, no need for compensation 571 if (diff > 33) { 572 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 573 BID_RETURN (res); 574 } // difference cannot be greater than 10^33 575 576 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 577 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 578 579 580 // if postitive, return whichever significand is larger 581 // (converse if negative) 582 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 583 && sig_n_prime256.w[1] == sig_y.w[1] 584 && (sig_n_prime256.w[0] == sig_y.w[0])) { 585 res = 1; 586 BID_RETURN (res); 587 } // if equal, return 1 588 { 589 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 590 || (sig_n_prime256.w[1] > sig_y.w[1]) 591 || (sig_n_prime256.w[1] == sig_y.w[1] 592 && sig_n_prime256.w[0] > 593 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 594 BID_RETURN (res); 595 } 596 } 597 //else { //128 by 64 bit multiply -> 192 bits 598 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 599 600 // if postitive, return whichever significand is larger 601 // (converse if negative) 602 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 603 && (sig_n_prime192.w[0] == sig_y.w[0])) { 604 res = 1; 605 BID_RETURN (res); 606 } // if equal, return 1 607 { 608 res = (((sig_n_prime192.w[2] > 0) 609 || (sig_n_prime192.w[1] > sig_y.w[1]) 610 || (sig_n_prime192.w[1] == sig_y.w[1] 611 && sig_n_prime192.w[0] > 612 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 613 BID_RETURN (res); 614 } 615 } 616 617 diff = exp_y - exp_x; 618 619 // if exp_x is 33 less than exp_y, no need for compensation 620 if (diff > 33) { 621 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 622 BID_RETURN (res); 623 } 624 625 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 626 // adjust the y significand upwards 627 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 628 629 630 // if postitive, return whichever significand is larger 631 // (converse if negative) 632 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 633 && sig_n_prime256.w[1] == sig_x.w[1] 634 && (sig_n_prime256.w[0] == sig_x.w[0])) { 635 res = 1; 636 BID_RETURN (res); 637 } // if equal, return 1 638 { 639 res = ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0 640 && (sig_n_prime256.w[1] < sig_x.w[1] 641 || (sig_n_prime256.w[1] == sig_x.w[1] 642 && sig_n_prime256.w[0] < 643 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == 644 MASK_SIGN)); 645 BID_RETURN (res); 646 } 647 } 648 //else { //128 by 64 bit multiply -> 192 bits 649 // adjust the y significand upwards 650 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 651 652 // if postitive, return whichever significand is larger 653 // (converse if negative) 654 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 655 && (sig_n_prime192.w[0] == sig_x.w[0])) { 656 res = 1; 657 BID_RETURN (res); 658 } // if equal, return 1 659 { 660 res = (sig_n_prime192.w[2] == 0 661 && (sig_n_prime192.w[1] < sig_x.w[1] 662 || (sig_n_prime192.w[1] == sig_x.w[1] 663 && sig_n_prime192.w[0] < 664 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 665 BID_RETURN (res); 666 } 667 } 668 669 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, 670 bid128_quiet_greater_unordered, 671 x, y) 672 673 int res; 674 int exp_x, exp_y; 675 int diff; 676 UINT128 sig_x, sig_y; 677 UINT192 sig_n_prime192; 678 UINT256 sig_n_prime256; 679 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 680 681 // NaN (CASE1) 682 // if either number is NAN, the comparison is unordered, 683 // rather than 684 // equal : return 1 685 if (((x.w[1] & MASK_NAN) == MASK_NAN) 686 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 687 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 688 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 689 *pfpsf |= INVALID_EXCEPTION; 690 } 691 { 692 res = 1; 693 BID_RETURN (res); 694 } 695 } 696 // SIMPLE (CASE2) 697 // if all the bits are the same, these numbers are equal (not Greater). 698 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 699 res = 0; 700 BID_RETURN (res); 701 } 702 // INFINITY (CASE3) 703 if ((x.w[1] & MASK_INF) == MASK_INF) { 704 // if x is neg infinity, there is no way it is greater than y, return 0 705 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) { 706 res = 0; 707 BID_RETURN (res); 708 } 709 // x is pos infinity, it is greater, unless y is positive infinity => 710 // return y!=pos_infinity 711 else { 712 res = (((y.w[1] & MASK_INF) != MASK_INF) 713 || ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 714 BID_RETURN (res); 715 } 716 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 717 // x is finite, so if y is positive infinity, then x is less, return 0 718 // if y is negative infinity, then x is greater, return 1 719 { 720 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 721 BID_RETURN (res); 722 } 723 } 724 // CONVERT X 725 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 726 sig_x.w[0] = x.w[0]; 727 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 728 729 // CHECK IF X IS CANONICAL 730 // 9999999999999999999999999999999999(decimal) = 731 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 732 // [0, 10^34) is the 754r supported canonical range. 733 // If the value exceeds that, it is interpreted as 0. 734 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 735 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 736 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 737 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 738 non_canon_x = 1; 739 else 740 non_canon_x = 0; 741 742 // CONVERT Y 743 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 744 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 745 sig_y.w[0] = y.w[0]; 746 747 // CHECK IF Y IS CANONICAL 748 // 9999999999999999999999999999999999(decimal) = 749 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 750 // [0, 10^34) is the 754r supported canonical range. 751 // If the value exceeds that, it is interpreted as 0. 752 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 753 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 754 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 755 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 756 non_canon_y = 1; 757 else 758 non_canon_y = 0; 759 760 // ZERO (CASE4) 761 // some properties: 762 // (+ZERO == -ZERO) => therefore ignore the sign 763 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 764 // ignore the exponent field 765 // (Any non-canonical # is considered 0) 766 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 767 x_is_zero = 1; 768 } 769 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 770 y_is_zero = 1; 771 } 772 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 773 if (x_is_zero && y_is_zero) { 774 res = 0; 775 BID_RETURN (res); 776 } 777 // is x is zero, it is greater if Y is negative 778 else if (x_is_zero) { 779 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 780 BID_RETURN (res); 781 } 782 // is y is zero, X is greater if it is positive 783 else if (y_is_zero) { 784 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 785 BID_RETURN (res); 786 } 787 // OPPOSITE SIGN (CASE5) 788 // now, if the sign bits differ, x is greater if y is negative 789 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 790 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 791 BID_RETURN (res); 792 } 793 // REDUNDANT REPRESENTATIONS (CASE6) 794 // if exponents are the same, then we have a simple comparison of the 795 // significands 796 if (exp_y == exp_x) { 797 res = (((sig_x.w[1] > sig_y.w[1]) 798 || (sig_x.w[1] == sig_y.w[1] 799 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) == 800 MASK_SIGN)); 801 BID_RETURN (res); 802 } 803 // if both components are either bigger or smaller, 804 // it is clear what needs to be done 805 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0] 806 && exp_x > exp_y) { 807 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 808 BID_RETURN (res); 809 } 810 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0] 811 && exp_x < exp_y) { 812 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 813 BID_RETURN (res); 814 } 815 816 diff = exp_x - exp_y; 817 818 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 819 if (diff > 0) { // to simplify the loop below, 820 821 // if exp_x is 33 greater than exp_y, no need for compensation 822 if (diff > 33) { 823 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 824 BID_RETURN (res); 825 } // difference cannot be greater than 10^33 826 827 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 828 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 829 830 831 // if postitive, return whichever significand is larger 832 // (converse if negative) 833 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 834 && sig_n_prime256.w[1] == sig_y.w[1] 835 && (sig_n_prime256.w[0] == sig_y.w[0])) { 836 res = 0; 837 BID_RETURN (res); 838 } // if equal, return 0 839 { 840 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 841 || (sig_n_prime256.w[1] > sig_y.w[1]) 842 || (sig_n_prime256.w[1] == sig_y.w[1] 843 && sig_n_prime256.w[0] > 844 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 845 BID_RETURN (res); 846 } 847 } 848 //else { //128 by 64 bit multiply -> 192 bits 849 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 850 851 // if postitive, return whichever significand is larger 852 // (converse if negative) 853 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 854 && (sig_n_prime192.w[0] == sig_y.w[0])) { 855 res = 0; 856 BID_RETURN (res); 857 } // if equal, return 0 858 { 859 res = (((sig_n_prime192.w[2] > 0) 860 || (sig_n_prime192.w[1] > sig_y.w[1]) 861 || (sig_n_prime192.w[1] == sig_y.w[1] 862 && sig_n_prime192.w[0] > 863 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 864 BID_RETURN (res); 865 } 866 } 867 868 diff = exp_y - exp_x; 869 870 // if exp_x is 33 less than exp_y, no need for compensation 871 if (diff > 33) { 872 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 873 BID_RETURN (res); 874 } 875 876 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 877 // adjust the y significand upwards 878 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 879 880 881 // if postitive, return whichever significand is larger 882 // (converse if negative) 883 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 884 && sig_n_prime256.w[1] == sig_x.w[1] 885 && (sig_n_prime256.w[0] == sig_x.w[0])) { 886 res = 0; 887 BID_RETURN (res); 888 } // if equal, return 0 889 { 890 res = ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0 891 && (sig_n_prime256.w[1] < sig_x.w[1] 892 || (sig_n_prime256.w[1] == sig_x.w[1] 893 && sig_n_prime256.w[0] < 894 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == 895 MASK_SIGN)); 896 BID_RETURN (res); 897 } 898 } 899 //else { //128 by 64 bit multiply -> 192 bits 900 // adjust the y significand upwards 901 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 902 903 // if postitive, return whichever significand is larger 904 // (converse if negative) 905 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 906 && (sig_n_prime192.w[0] == sig_x.w[0])) { 907 res = 0; 908 BID_RETURN (res); 909 } // if equal, return 0 910 { 911 res = (sig_n_prime192.w[2] == 0 912 && (sig_n_prime192.w[1] < sig_x.w[1] 913 || (sig_n_prime192.w[1] == sig_x.w[1] 914 && sig_n_prime192.w[0] < 915 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 916 BID_RETURN (res); 917 } 918 } 919 920 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_less, x, y) 921 922 int res; 923 int exp_x, exp_y; 924 int diff; 925 UINT128 sig_x, sig_y; 926 UINT192 sig_n_prime192; 927 UINT256 sig_n_prime256; 928 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 929 930 // NaN (CASE1) 931 // if either number is NAN, the comparison is unordered, 932 // rather than equal : return 0 933 if (((x.w[1] & MASK_NAN) == MASK_NAN) 934 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 935 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 936 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 937 *pfpsf |= INVALID_EXCEPTION; 938 } 939 { 940 res = 0; 941 BID_RETURN (res); 942 } 943 } 944 // SIMPLE (CASE2) 945 // if all the bits are the same, these numbers are equal. 946 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 947 res = 0; 948 BID_RETURN (res); 949 } 950 // INFINITY (CASE3) 951 if ((x.w[1] & MASK_INF) == MASK_INF) { 952 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } 953 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) 954 // x is -inf, so it is less than y unless y is -inf 955 { 956 res = (((y.w[1] & MASK_INF) != MASK_INF) 957 || (y.w[1] & MASK_SIGN) != MASK_SIGN); 958 BID_RETURN (res); 959 } else 960 // x is pos_inf, no way for it to be less than y 961 { 962 res = 0; 963 BID_RETURN (res); 964 } 965 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 966 // x is finite, so if y is positive infinity, then x is less, return 0 967 // if y is negative infinity, then x is greater, return 1 968 { 969 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 970 BID_RETURN (res); 971 } 972 } 973 // CONVERT X 974 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 975 sig_x.w[0] = x.w[0]; 976 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 977 978 // CHECK IF X IS CANONICAL 979 // 9999999999999999999999999999999999(decimal) = 980 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 981 // [0, 10^34) is the 754r supported canonical range. 982 // If the value exceeds that, it is interpreted as 0. 983 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 984 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 985 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 986 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 987 non_canon_x = 1; 988 else 989 non_canon_x = 0; 990 991 // CONVERT Y 992 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 993 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 994 sig_y.w[0] = y.w[0]; 995 996 // CHECK IF Y IS CANONICAL 997 // 9999999999999999999999999999999999(decimal) = 998 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 999 // [0, 10^34) is the 754r supported canonical range. 1000 // If the value exceeds that, it is interpreted as 0. 1001 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 1002 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 1003 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 1004 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 1005 non_canon_y = 1; 1006 else 1007 non_canon_y = 0; 1008 1009 // ZERO (CASE4) 1010 // some properties: 1011 // (+ZERO == -ZERO) => therefore ignore the sign 1012 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 1013 // ignore the exponent field 1014 // (Any non-canonical # is considered 0) 1015 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1016 x_is_zero = 1; 1017 } 1018 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 1019 y_is_zero = 1; 1020 } 1021 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 1022 if (x_is_zero && y_is_zero) { 1023 res = 0; 1024 BID_RETURN (res); 1025 } 1026 // is x is zero, it is greater if Y is negative 1027 else if (x_is_zero) { 1028 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1029 BID_RETURN (res); 1030 } 1031 // is y is zero, X is greater if it is positive 1032 else if (y_is_zero) { 1033 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1034 BID_RETURN (res); 1035 } 1036 // OPPOSITE SIGN (CASE5) 1037 // now, if the sign bits differ, x is greater if y is negative 1038 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 1039 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1040 BID_RETURN (res); 1041 } 1042 // REDUNDANT REPRESENTATIONS (CASE6) 1043 // if exponents are the same, then we have a simple comparison of the 1044 // significands 1045 if (exp_y == exp_x) { 1046 res = (((sig_x.w[1] > sig_y.w[1]) 1047 || (sig_x.w[1] == sig_y.w[1] 1048 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) != 1049 MASK_SIGN)); 1050 BID_RETURN (res); 1051 } 1052 // if both components are either bigger or smaller, 1053 // it is clear what needs to be done 1054 if ((sig_x.w[1] > sig_y.w[1] 1055 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 1056 && exp_x >= exp_y) { 1057 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1058 BID_RETURN (res); 1059 } 1060 if ((sig_x.w[1] < sig_y.w[1] 1061 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 1062 && exp_x <= exp_y) { 1063 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1064 BID_RETURN (res); 1065 } 1066 1067 diff = exp_x - exp_y; 1068 1069 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 1070 if (diff > 0) { // to simplify the loop below, 1071 1072 // if exp_x is 33 greater than exp_y, no need for compensation 1073 if (diff > 33) { 1074 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1075 BID_RETURN (res); 1076 } // difference cannot be greater than 10^33 1077 1078 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 1079 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 1080 1081 1082 // if postitive, return whichever significand is larger 1083 // (converse if negative) 1084 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 1085 && sig_n_prime256.w[1] == sig_y.w[1] 1086 && (sig_n_prime256.w[0] == sig_y.w[0])) { 1087 res = 0; 1088 BID_RETURN (res); 1089 } // if equal, return 0 1090 { 1091 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 1092 || (sig_n_prime256.w[1] > sig_y.w[1]) 1093 || (sig_n_prime256.w[1] == sig_y.w[1] 1094 && sig_n_prime256.w[0] > 1095 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 1096 BID_RETURN (res); 1097 } 1098 } 1099 //else { //128 by 64 bit multiply -> 192 bits 1100 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 1101 1102 // if postitive, return whichever significand is larger 1103 // (converse if negative) 1104 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 1105 && (sig_n_prime192.w[0] == sig_y.w[0])) { 1106 res = 0; 1107 BID_RETURN (res); 1108 } // if equal, return 0 1109 { 1110 res = (((sig_n_prime192.w[2] > 0) 1111 || (sig_n_prime192.w[1] > sig_y.w[1]) 1112 || (sig_n_prime192.w[1] == sig_y.w[1] 1113 && sig_n_prime192.w[0] > 1114 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 1115 BID_RETURN (res); 1116 } 1117 } 1118 1119 diff = exp_y - exp_x; 1120 1121 // if exp_x is 33 less than exp_y, no need for compensation 1122 if (diff > 33) { 1123 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1124 BID_RETURN (res); 1125 } 1126 1127 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 1128 // adjust the y significand upwards 1129 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 1130 1131 // if postitive, return whichever significand is larger 1132 // (converse if negative) 1133 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 1134 && sig_n_prime256.w[1] == sig_x.w[1] 1135 && (sig_n_prime256.w[0] == sig_x.w[0])) { 1136 res = 0; 1137 BID_RETURN (res); 1138 } // if equal, return 1 1139 { 1140 res = ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 1141 || (sig_n_prime256.w[1] > sig_x.w[1] 1142 || (sig_n_prime256.w[1] == sig_x.w[1] 1143 && sig_n_prime256.w[0] > 1144 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == 1145 MASK_SIGN)); 1146 BID_RETURN (res); 1147 } 1148 } 1149 //else { //128 by 64 bit multiply -> 192 bits 1150 // adjust the y significand upwards 1151 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 1152 1153 // if postitive, return whichever significand is larger 1154 // (converse if negative) 1155 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 1156 && (sig_n_prime192.w[0] == sig_x.w[0])) { 1157 res = 0; 1158 BID_RETURN (res); 1159 } // if equal, return 0 1160 { 1161 res = (sig_n_prime192.w[2] != 0 1162 || (sig_n_prime192.w[1] > sig_x.w[1] 1163 || (sig_n_prime192.w[1] == sig_x.w[1] 1164 && sig_n_prime192.w[0] > 1165 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 1166 BID_RETURN (res); 1167 } 1168 } 1169 1170 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_less_equal, 1171 x, y) 1172 1173 int res; 1174 int exp_x, exp_y; 1175 int diff; 1176 UINT128 sig_x, sig_y; 1177 UINT192 sig_n_prime192; 1178 UINT256 sig_n_prime256; 1179 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 1180 1181 // NaN (CASE1) 1182 // if either number is NAN, the comparison is unordered, 1183 // rather than equal : return 0 1184 if (((x.w[1] & MASK_NAN) == MASK_NAN) 1185 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 1186 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 1187 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 1188 *pfpsf |= INVALID_EXCEPTION; 1189 } 1190 { 1191 res = 0; 1192 BID_RETURN (res); 1193 } 1194 } 1195 // SIMPLE (CASE2) 1196 // if all the bits are the same, these numbers are equal (not Greater). 1197 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 1198 res = 1; 1199 BID_RETURN (res); 1200 } 1201 // INFINITY (CASE3) 1202 if ((x.w[1] & MASK_INF) == MASK_INF) { 1203 // if x is neg infinity, there is no way it is greater than y, return 1 1204 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) { 1205 res = 1; 1206 BID_RETURN (res); 1207 } 1208 // x is pos infinity, it is greater, unless y is positive infinity => 1209 // return y!=pos_infinity 1210 else { 1211 res = (((y.w[1] & MASK_INF) == MASK_INF) 1212 && ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 1213 BID_RETURN (res); 1214 } 1215 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 1216 // x is finite, so if y is positive infinity, then x is less, return 0 1217 // if y is negative infinity, then x is greater, return 1 1218 { 1219 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1220 BID_RETURN (res); 1221 } 1222 } 1223 // CONVERT X 1224 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 1225 sig_x.w[0] = x.w[0]; 1226 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 1227 1228 // CHECK IF X IS CANONICAL 1229 // 9999999999999999999999999999999999(decimal) = 1230 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1231 // [0, 10^34) is the 754r supported canonical range. 1232 // If the value exceeds that, it is interpreted as 0. 1233 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 1234 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 1235 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 1236 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 1237 non_canon_x = 1; 1238 else 1239 non_canon_x = 0; 1240 1241 // CONVERT Y 1242 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 1243 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 1244 sig_y.w[0] = y.w[0]; 1245 1246 // CHECK IF Y IS CANONICAL 1247 // 9999999999999999999999999999999999(decimal) = 1248 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1249 // [0, 10^34) is the 754r supported canonical range. 1250 // If the value exceeds that, it is interpreted as 0. 1251 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 1252 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 1253 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 1254 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 1255 non_canon_y = 1; 1256 else 1257 non_canon_y = 0; 1258 1259 // ZERO (CASE4) 1260 // some properties: 1261 // (+ZERO == -ZERO) => therefore ignore the sign 1262 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 1263 // ignore the exponent field 1264 // (Any non-canonical # is considered 0) 1265 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1266 x_is_zero = 1; 1267 } 1268 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 1269 y_is_zero = 1; 1270 } 1271 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 1272 if (x_is_zero && y_is_zero) { 1273 res = 1; 1274 BID_RETURN (res); 1275 } 1276 // is x is zero, it is greater if Y is negative 1277 else if (x_is_zero) { 1278 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1279 BID_RETURN (res); 1280 } 1281 // is y is zero, X is greater if it is positive 1282 else if (y_is_zero) { 1283 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1284 BID_RETURN (res); 1285 } 1286 // OPPOSITE SIGN (CASE5) 1287 // now, if the sign bits differ, x is greater if y is negative 1288 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 1289 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1290 BID_RETURN (res); 1291 } 1292 // REDUNDANT REPRESENTATIONS (CASE6) 1293 // if exponents are the same, then we have a simple comparison of the 1294 // significands 1295 if (exp_y == exp_x) { 1296 res = (((sig_x.w[1] > sig_y.w[1]) || (sig_x.w[1] == sig_y.w[1] && 1297 sig_x.w[0] >= 1298 sig_y.w[0])) ^ ((x. 1299 w[1] & 1300 MASK_SIGN) != 1301 MASK_SIGN)); 1302 BID_RETURN (res); 1303 } 1304 // if both components are either bigger or smaller, 1305 // it is clear what needs to be done 1306 if ((sig_x.w[1] > sig_y.w[1] 1307 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 1308 && exp_x >= exp_y) { 1309 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1310 BID_RETURN (res); 1311 } 1312 if ((sig_x.w[1] < sig_y.w[1] 1313 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 1314 && exp_x <= exp_y) { 1315 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1316 BID_RETURN (res); 1317 } 1318 1319 diff = exp_x - exp_y; 1320 1321 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 1322 if (diff > 0) { // to simplify the loop below, 1323 1324 // if exp_x is 33 greater than exp_y, no need for compensation 1325 if (diff > 33) { 1326 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1327 BID_RETURN (res); 1328 } // difference cannot be greater than 10^33 1329 1330 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 1331 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 1332 1333 1334 // if postitive, return whichever significand is larger 1335 // (converse if negative) 1336 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 1337 && sig_n_prime256.w[1] == sig_y.w[1] 1338 && (sig_n_prime256.w[0] == sig_y.w[0])) { 1339 res = 1; 1340 BID_RETURN (res); 1341 } // if equal, return 0 1342 { 1343 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 1344 || (sig_n_prime256.w[1] > sig_y.w[1]) 1345 || (sig_n_prime256.w[1] == sig_y.w[1] 1346 && sig_n_prime256.w[0] > 1347 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 1348 BID_RETURN (res); 1349 } 1350 } 1351 //else { //128 by 64 bit multiply -> 192 bits 1352 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 1353 1354 // if postitive, return whichever significand is larger 1355 // (converse if negative) 1356 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 1357 && (sig_n_prime192.w[0] == sig_y.w[0])) { 1358 res = 1; 1359 BID_RETURN (res); 1360 } // if equal, return 0 1361 { 1362 res = (((sig_n_prime192.w[2] > 0) 1363 || (sig_n_prime192.w[1] > sig_y.w[1]) 1364 || (sig_n_prime192.w[1] == sig_y.w[1] 1365 && sig_n_prime192.w[0] > 1366 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 1367 BID_RETURN (res); 1368 } 1369 } 1370 1371 diff = exp_y - exp_x; 1372 1373 // if exp_x is 33 less than exp_y, no need for compensation 1374 if (diff > 33) { 1375 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1376 BID_RETURN (res); 1377 } 1378 1379 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 1380 // adjust the y significand upwards 1381 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 1382 1383 1384 // if postitive, return whichever significand is larger 1385 // (converse if negative) 1386 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 1387 && sig_n_prime256.w[1] == sig_x.w[1] 1388 && (sig_n_prime256.w[0] == sig_x.w[0])) { 1389 res = 1; 1390 BID_RETURN (res); 1391 } // if equal, return 0 1392 { 1393 res = 1394 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 1395 || (sig_n_prime256.w[1] > sig_x.w[1] 1396 || (sig_n_prime256.w[1] == sig_x.w[1] 1397 && sig_n_prime256.w[0] > 1398 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 1399 BID_RETURN (res); 1400 } 1401 } 1402 //else { //128 by 64 bit multiply -> 192 bits 1403 // adjust the y significand upwards 1404 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 1405 1406 // if postitive, return whichever significand is larger 1407 // (converse if negative) 1408 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 1409 && (sig_n_prime192.w[0] == sig_x.w[0])) { 1410 res = 1; 1411 BID_RETURN (res); 1412 } // if equal, return 0 1413 { 1414 res = (sig_n_prime192.w[2] != 0 1415 || (sig_n_prime192.w[1] > sig_x.w[1] 1416 || (sig_n_prime192.w[1] == sig_x.w[1] 1417 && sig_n_prime192.w[0] > 1418 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 1419 BID_RETURN (res); 1420 } 1421 } 1422 1423 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, 1424 bid128_quiet_less_unordered, 1425 x, y) 1426 1427 int res; 1428 int exp_x, exp_y; 1429 int diff; 1430 UINT128 sig_x, sig_y; 1431 UINT192 sig_n_prime192; 1432 UINT256 sig_n_prime256; 1433 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 1434 1435 // NaN (CASE1) 1436 // if either number is NAN, the comparison is unordered 1437 if (((x.w[1] & MASK_NAN) == MASK_NAN) 1438 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 1439 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 1440 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 1441 *pfpsf |= INVALID_EXCEPTION; 1442 } 1443 { 1444 res = 1; 1445 BID_RETURN (res); 1446 } 1447 } 1448 // SIMPLE (CASE2) 1449 // if all the bits are the same, these numbers are equal. 1450 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 1451 res = 0; 1452 BID_RETURN (res); 1453 } 1454 // INFINITY (CASE3) 1455 if ((x.w[1] & MASK_INF) == MASK_INF) { 1456 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } 1457 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) 1458 // x is -inf, so it is less than y unless y is -inf 1459 { 1460 res = (((y.w[1] & MASK_INF) != MASK_INF) 1461 || (y.w[1] & MASK_SIGN) != MASK_SIGN); 1462 BID_RETURN (res); 1463 } else 1464 // x is pos_inf, no way for it to be less than y 1465 { 1466 res = 0; 1467 BID_RETURN (res); 1468 } 1469 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 1470 // x is finite, so if y is positive infinity, then x is less, return 0 1471 // if y is negative infinity, then x is greater, return 1 1472 { 1473 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1474 BID_RETURN (res); 1475 } 1476 } 1477 // CONVERT X 1478 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 1479 sig_x.w[0] = x.w[0]; 1480 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 1481 1482 // CHECK IF X IS CANONICAL 1483 // 9999999999999999999999999999999999(decimal) = 1484 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1485 // [0, 10^34) is the 754r supported canonical range. 1486 // If the value exceeds that, it is interpreted as 0. 1487 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 1488 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 1489 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 1490 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 1491 non_canon_x = 1; 1492 else 1493 non_canon_x = 0; 1494 1495 // CONVERT Y 1496 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 1497 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 1498 sig_y.w[0] = y.w[0]; 1499 1500 // CHECK IF Y IS CANONICAL 1501 // 9999999999999999999999999999999999(decimal) = 1502 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1503 // [0, 10^34) is the 754r supported canonical range. 1504 // If the value exceeds that, it is interpreted as 0. 1505 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 1506 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 1507 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 1508 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 1509 non_canon_y = 1; 1510 else 1511 non_canon_y = 0; 1512 1513 // ZERO (CASE4) 1514 // some properties: 1515 // (+ZERO == -ZERO) => therefore ignore the sign 1516 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 1517 // ignore the exponent field 1518 // (Any non-canonical # is considered 0) 1519 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1520 x_is_zero = 1; 1521 } 1522 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 1523 y_is_zero = 1; 1524 } 1525 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 1526 if (x_is_zero && y_is_zero) { 1527 res = 0; 1528 BID_RETURN (res); 1529 } 1530 // is x is zero, it is greater if Y is negative 1531 else if (x_is_zero) { 1532 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1533 BID_RETURN (res); 1534 } 1535 // is y is zero, X is greater if it is positive 1536 else if (y_is_zero) { 1537 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1538 BID_RETURN (res); 1539 } 1540 // OPPOSITE SIGN (CASE5) 1541 // now, if the sign bits differ, x is greater if y is negative 1542 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 1543 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1544 BID_RETURN (res); 1545 } 1546 // REDUNDANT REPRESENTATIONS (CASE6) 1547 // if exponents are the same, then we have a simple comparison 1548 // of the significands 1549 if (exp_y == exp_x) { 1550 res = (((sig_x.w[1] > sig_y.w[1]) 1551 || (sig_x.w[1] == sig_y.w[1] 1552 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) != 1553 MASK_SIGN)); 1554 BID_RETURN (res); 1555 } 1556 // if both components are either bigger or smaller, 1557 // it is clear what needs to be done 1558 if ((sig_x.w[1] > sig_y.w[1] 1559 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 1560 && exp_x >= exp_y) { 1561 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1562 BID_RETURN (res); 1563 } 1564 if ((sig_x.w[1] < sig_y.w[1] 1565 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 1566 && exp_x <= exp_y) { 1567 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1568 BID_RETURN (res); 1569 } 1570 1571 diff = exp_x - exp_y; 1572 1573 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 1574 if (diff > 0) { // to simplify the loop below, 1575 1576 // if exp_x is 33 greater than exp_y, no need for compensation 1577 if (diff > 33) { 1578 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1579 BID_RETURN (res); 1580 } // difference cannot be greater than 10^33 1581 1582 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 1583 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 1584 1585 1586 // if postitive, return whichever significand is larger 1587 // (converse if negative) 1588 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 1589 && sig_n_prime256.w[1] == sig_y.w[1] 1590 && (sig_n_prime256.w[0] == sig_y.w[0])) { 1591 res = 0; 1592 BID_RETURN (res); 1593 } // if equal, return 0 1594 { 1595 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 1596 || (sig_n_prime256.w[1] > sig_y.w[1]) 1597 || (sig_n_prime256.w[1] == sig_y.w[1] 1598 && sig_n_prime256.w[0] > 1599 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 1600 BID_RETURN (res); 1601 } 1602 } 1603 //else { //128 by 64 bit multiply -> 192 bits 1604 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 1605 1606 // if postitive, return whichever significand is larger 1607 // (converse if negative) 1608 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 1609 && (sig_n_prime192.w[0] == sig_y.w[0])) { 1610 res = 0; 1611 BID_RETURN (res); 1612 } // if equal, return 0 1613 { 1614 res = (((sig_n_prime192.w[2] > 0) 1615 || (sig_n_prime192.w[1] > sig_y.w[1]) 1616 || (sig_n_prime192.w[1] == sig_y.w[1] 1617 && sig_n_prime192.w[0] > 1618 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 1619 BID_RETURN (res); 1620 } 1621 } 1622 1623 diff = exp_y - exp_x; 1624 1625 // if exp_x is 33 less than exp_y, no need for compensation 1626 if (diff > 33) { 1627 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1628 BID_RETURN (res); 1629 } 1630 1631 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 1632 // adjust the y significand upwards 1633 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 1634 1635 1636 // if postitive, return whichever significand is larger 1637 // (converse if negative) 1638 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 1639 && sig_n_prime256.w[1] == sig_x.w[1] 1640 && (sig_n_prime256.w[0] == sig_x.w[0])) { 1641 res = 0; 1642 BID_RETURN (res); 1643 } // if equal, return 1 1644 { 1645 res = 1646 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 1647 || (sig_n_prime256.w[1] > sig_x.w[1] 1648 || (sig_n_prime256.w[1] == sig_x.w[1] 1649 && sig_n_prime256.w[0] > 1650 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 1651 BID_RETURN (res); 1652 } 1653 } 1654 //else { //128 by 64 bit multiply -> 192 bits 1655 // adjust the y significand upwards 1656 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 1657 1658 // if postitive, return whichever significand is larger 1659 // (converse if negative) 1660 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 1661 && (sig_n_prime192.w[0] == sig_x.w[0])) { 1662 res = 0; 1663 BID_RETURN (res); 1664 } // if equal, return 0 1665 { 1666 res = (sig_n_prime192.w[2] != 0 1667 || (sig_n_prime192.w[1] > sig_x.w[1] 1668 || (sig_n_prime192.w[1] == sig_x.w[1] 1669 && sig_n_prime192.w[0] > 1670 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 1671 BID_RETURN (res); 1672 } 1673 } 1674 1675 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_not_equal, 1676 x, y) 1677 1678 int res; 1679 int exp_x, exp_y, exp_t; 1680 UINT128 sig_x, sig_y, sig_t; 1681 UINT192 sig_n_prime192; 1682 UINT256 sig_n_prime256; 1683 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 1684 1685 // NaN (CASE1) 1686 // if either number is NAN, the comparison is unordered, 1687 // rather than equal : return 0 1688 if (((x.w[1] & MASK_NAN) == MASK_NAN) 1689 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 1690 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 1691 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 1692 *pfpsf |= INVALID_EXCEPTION; 1693 } 1694 { 1695 res = 1; 1696 BID_RETURN (res); 1697 } 1698 } 1699 // SIMPLE (CASE2) 1700 // if all the bits are the same, these numbers are equivalent. 1701 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 1702 res = 0; 1703 BID_RETURN (res); 1704 } 1705 // INFINITY (CASE3) 1706 if ((x.w[1] & MASK_INF) == MASK_INF) { 1707 if ((y.w[1] & MASK_INF) == MASK_INF) { 1708 res = (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN); 1709 BID_RETURN (res); 1710 } else { 1711 res = 1; 1712 BID_RETURN (res); 1713 } 1714 } 1715 if ((y.w[1] & MASK_INF) == MASK_INF) { 1716 res = 1; 1717 BID_RETURN (res); 1718 } 1719 // CONVERT X 1720 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 1721 sig_x.w[0] = x.w[0]; 1722 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 1723 1724 // CHECK IF X IS CANONICAL 1725 // 9999999999999999999999999999999999(decimal) = 1726 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1727 // [0, 10^34) is the 754r supported canonical range. 1728 // If the value exceeds that, it is interpreted as 0. 1729 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 1730 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 1731 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 1732 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 1733 non_canon_x = 1; 1734 else 1735 non_canon_x = 0; 1736 1737 // CONVERT Y 1738 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 1739 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 1740 sig_y.w[0] = y.w[0]; 1741 1742 // CHECK IF Y IS CANONICAL 1743 // 9999999999999999999999999999999999(decimal) = 1744 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1745 // [0, 10^34) is the 754r supported canonical range. 1746 // If the value exceeds that, it is interpreted as 0. 1747 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 1748 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 1749 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 1750 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 1751 non_canon_y = 1; 1752 else 1753 non_canon_y = 0; 1754 1755 // some properties: 1756 // (+ZERO == -ZERO) => therefore ignore the sign 1757 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 1758 // ignore the exponent field 1759 // (Any non-canonical # is considered 0) 1760 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1761 x_is_zero = 1; 1762 } 1763 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 1764 y_is_zero = 1; 1765 } 1766 1767 if (x_is_zero && y_is_zero) { 1768 res = 0; 1769 BID_RETURN (res); 1770 } else if ((x_is_zero && !y_is_zero) || (!x_is_zero && y_is_zero)) { 1771 res = 1; 1772 BID_RETURN (res); 1773 } 1774 // OPPOSITE SIGN (CASE5) 1775 // now, if the sign bits differ => not equal : return 0 1776 if ((x.w[1] ^ y.w[1]) & MASK_SIGN) { 1777 res = 1; 1778 BID_RETURN (res); 1779 } 1780 // REDUNDANT REPRESENTATIONS (CASE6) 1781 if (exp_x > exp_y) { // to simplify the loop below, 1782 SWAP (exp_x, exp_y, exp_t); // put the larger exp in y, 1783 SWAP (sig_x.w[1], sig_y.w[1], sig_t.w[1]); // and the smaller exp in x 1784 SWAP (sig_x.w[0], sig_y.w[0], sig_t.w[0]); // and the smaller exp in x 1785 } 1786 1787 1788 if (exp_y - exp_x > 33) { 1789 res = 1; 1790 BID_RETURN (res); 1791 } // difference cannot be greater than 10^33 1792 1793 if (exp_y - exp_x > 19) { 1794 // recalculate y's significand upwards 1795 __mul_128x128_to_256 (sig_n_prime256, sig_y, 1796 ten2k128[exp_y - exp_x - 20]); 1797 { 1798 res = ((sig_n_prime256.w[3] != 0) || (sig_n_prime256.w[2] != 0) 1799 || (sig_n_prime256.w[1] != sig_x.w[1]) 1800 || (sig_n_prime256.w[0] != sig_x.w[0])); 1801 BID_RETURN (res); 1802 } 1803 1804 } 1805 //else{ 1806 // recalculate y's significand upwards 1807 __mul_64x128_to192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y); 1808 { 1809 res = ((sig_n_prime192.w[2] != 0) 1810 || (sig_n_prime192.w[1] != sig_x.w[1]) 1811 || (sig_n_prime192.w[0] != sig_x.w[0])); 1812 BID_RETURN (res); 1813 } 1814 } 1815 1816 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_not_greater, 1817 x, y) 1818 1819 int res; 1820 int exp_x, exp_y; 1821 int diff; 1822 UINT128 sig_x, sig_y; 1823 UINT192 sig_n_prime192; 1824 UINT256 sig_n_prime256; 1825 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 1826 1827 // NaN (CASE1) 1828 // if either number is NAN, the comparison is unordered, 1829 // rather than equal : return 0 1830 if (((x.w[1] & MASK_NAN) == MASK_NAN) 1831 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 1832 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 1833 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 1834 *pfpsf |= INVALID_EXCEPTION; 1835 } 1836 { 1837 res = 1; 1838 BID_RETURN (res); 1839 } 1840 } 1841 // SIMPLE (CASE2) 1842 // if all the bits are the same, these numbers are equal (not Greater). 1843 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 1844 res = 1; 1845 BID_RETURN (res); 1846 } 1847 // INFINITY (CASE3) 1848 if ((x.w[1] & MASK_INF) == MASK_INF) { 1849 // if x is neg infinity, there is no way it is greater than y, return 1 1850 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) { 1851 res = 1; 1852 BID_RETURN (res); 1853 } 1854 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity 1855 else { 1856 res = (((y.w[1] & MASK_INF) == MASK_INF) 1857 && ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 1858 BID_RETURN (res); 1859 } 1860 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 1861 // x is finite, so if y is positive infinity, then x is less, return 0 1862 // if y is negative infinity, then x is greater, return 1 1863 { 1864 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1865 BID_RETURN (res); 1866 } 1867 } 1868 // CONVERT X 1869 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 1870 sig_x.w[0] = x.w[0]; 1871 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 1872 1873 // CHECK IF X IS CANONICAL 1874 // 9999999999999999999999999999999999(decimal) = 1875 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1876 // [0, 10^34) is the 754r supported canonical range. 1877 // If the value exceeds that, it is interpreted as 0. 1878 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 1879 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 1880 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 1881 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 1882 non_canon_x = 1; 1883 else 1884 non_canon_x = 0; 1885 1886 // CONVERT Y 1887 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 1888 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 1889 sig_y.w[0] = y.w[0]; 1890 1891 // CHECK IF Y IS CANONICAL 1892 // 9999999999999999999999999999999999(decimal) = 1893 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1894 // [0, 10^34) is the 754r supported canonical range. 1895 // If the value exceeds that, it is interpreted as 0. 1896 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 1897 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 1898 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 1899 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 1900 non_canon_y = 1; 1901 else 1902 non_canon_y = 0; 1903 1904 // ZERO (CASE4) 1905 // some properties: 1906 // (+ZERO == -ZERO) => therefore ignore the sign 1907 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 1908 // ignore the exponent field 1909 // (Any non-canonical # is considered 0) 1910 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1911 x_is_zero = 1; 1912 } 1913 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 1914 y_is_zero = 1; 1915 } 1916 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 1917 if (x_is_zero && y_is_zero) { 1918 res = 1; 1919 BID_RETURN (res); 1920 } 1921 // is x is zero, it is greater if Y is negative 1922 else if (x_is_zero) { 1923 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1924 BID_RETURN (res); 1925 } 1926 // is y is zero, X is greater if it is positive 1927 else if (y_is_zero) { 1928 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1929 BID_RETURN (res); 1930 } 1931 // OPPOSITE SIGN (CASE5) 1932 // now, if the sign bits differ, x is greater if y is negative 1933 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 1934 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 1935 BID_RETURN (res); 1936 } 1937 // REDUNDANT REPRESENTATIONS (CASE6) 1938 // if exponents are the same, then we have a simple comparison 1939 // of the significands 1940 if (exp_y == exp_x) { 1941 res = (((sig_x.w[1] > sig_y.w[1]) 1942 || (sig_x.w[1] == sig_y.w[1] 1943 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) != 1944 MASK_SIGN)); 1945 BID_RETURN (res); 1946 } 1947 // if both components are either bigger or smaller, 1948 // it is clear what needs to be done 1949 if ((sig_x.w[1] > sig_y.w[1] 1950 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 1951 && exp_x >= exp_y) { 1952 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1953 BID_RETURN (res); 1954 } 1955 if ((sig_x.w[1] < sig_y.w[1] 1956 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 1957 && exp_x <= exp_y) { 1958 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1959 BID_RETURN (res); 1960 } 1961 1962 diff = exp_x - exp_y; 1963 1964 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 1965 if (diff > 0) { // to simplify the loop below, 1966 1967 // if exp_x is 33 greater than exp_y, no need for compensation 1968 if (diff > 33) { 1969 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 1970 BID_RETURN (res); 1971 } // difference cannot be greater than 10^33 1972 1973 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 1974 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 1975 1976 1977 // if postitive, return whichever significand is larger 1978 // (converse if negative) 1979 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 1980 && sig_n_prime256.w[1] == sig_y.w[1] 1981 && (sig_n_prime256.w[0] == sig_y.w[0])) { 1982 res = 1; 1983 BID_RETURN (res); 1984 } // if equal, return 0 1985 { 1986 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 1987 || (sig_n_prime256.w[1] > sig_y.w[1]) 1988 || (sig_n_prime256.w[1] == sig_y.w[1] 1989 && sig_n_prime256.w[0] > 1990 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 1991 BID_RETURN (res); 1992 } 1993 } 1994 //else { //128 by 64 bit multiply -> 192 bits 1995 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 1996 1997 // if postitive, return whichever significand is larger 1998 // (converse if negative) 1999 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 2000 && (sig_n_prime192.w[0] == sig_y.w[0])) { 2001 res = 1; 2002 BID_RETURN (res); 2003 } // if equal, return 0 2004 { 2005 res = (((sig_n_prime192.w[2] > 0) 2006 || (sig_n_prime192.w[1] > sig_y.w[1]) 2007 || (sig_n_prime192.w[1] == sig_y.w[1] 2008 && sig_n_prime192.w[0] > 2009 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 2010 BID_RETURN (res); 2011 } 2012 } 2013 2014 diff = exp_y - exp_x; 2015 2016 // if exp_x is 33 less than exp_y, no need for compensation 2017 if (diff > 33) { 2018 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2019 BID_RETURN (res); 2020 } 2021 2022 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 2023 // adjust the y significand upwards 2024 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 2025 2026 2027 // if postitive, return whichever significand is larger 2028 // (converse if negative) 2029 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 2030 && sig_n_prime256.w[1] == sig_x.w[1] 2031 && (sig_n_prime256.w[0] == sig_x.w[0])) { 2032 res = 1; 2033 BID_RETURN (res); 2034 } // if equal, return 0 2035 { 2036 res = 2037 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 2038 || (sig_n_prime256.w[1] > sig_x.w[1] 2039 || (sig_n_prime256.w[1] == sig_x.w[1] 2040 && sig_n_prime256.w[0] > 2041 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 2042 BID_RETURN (res); 2043 } 2044 } 2045 //else { //128 by 64 bit multiply -> 192 bits 2046 // adjust the y significand upwards 2047 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 2048 2049 // if postitive, return whichever significand is larger 2050 // (converse if negative) 2051 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 2052 && (sig_n_prime192.w[0] == sig_x.w[0])) { 2053 res = 1; 2054 BID_RETURN (res); 2055 } // if equal, return 0 2056 { 2057 res = (sig_n_prime192.w[2] != 0 2058 || (sig_n_prime192.w[1] > sig_x.w[1] 2059 || (sig_n_prime192.w[1] == sig_x.w[1] 2060 && sig_n_prime192.w[0] > 2061 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2062 BID_RETURN (res); 2063 } 2064 } 2065 2066 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_not_less, x, 2067 y) 2068 2069 int res; 2070 int exp_x, exp_y; 2071 int diff; 2072 UINT128 sig_x, sig_y; 2073 UINT192 sig_n_prime192; 2074 UINT256 sig_n_prime256; 2075 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 2076 2077 // NaN (CASE1) 2078 // if either number is NAN, the comparison is unordered, 2079 // rather than equal : return 1 2080 if (((x.w[1] & MASK_NAN) == MASK_NAN) 2081 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 2082 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 2083 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 2084 *pfpsf |= INVALID_EXCEPTION; 2085 } 2086 { 2087 res = 1; 2088 BID_RETURN (res); 2089 } 2090 } 2091 // SIMPLE (CASE2) 2092 // if all the bits are the same, these numbers are equal (not Greater). 2093 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 2094 res = 1; 2095 BID_RETURN (res); 2096 } 2097 // INFINITY (CASE3) 2098 if ((x.w[1] & MASK_INF) == MASK_INF) { 2099 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } 2100 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) 2101 // x is -inf, so it is less than y unless y is -inf 2102 { 2103 res = (((y.w[1] & MASK_INF) == MASK_INF) 2104 && (y.w[1] & MASK_SIGN) == MASK_SIGN); 2105 BID_RETURN (res); 2106 } else 2107 // x is pos_inf, no way for it to be less than y 2108 { 2109 res = 1; 2110 BID_RETURN (res); 2111 } 2112 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 2113 // x is finite, so if y is positive infinity, then x is less, return 0 2114 // if y is negative infinity, then x is greater, return 1 2115 { 2116 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2117 BID_RETURN (res); 2118 } 2119 } 2120 // CONVERT X 2121 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 2122 sig_x.w[0] = x.w[0]; 2123 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 2124 2125 // CHECK IF X IS CANONICAL 2126 // 9999999999999999999999999999999999(decimal) = 2127 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 2128 // [0, 10^34) is the 754r supported canonical range. 2129 // If the value exceeds that, it is interpreted as 0. 2130 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 2131 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 2132 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 2133 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 2134 non_canon_x = 1; 2135 else 2136 non_canon_x = 0; 2137 2138 // CONVERT Y 2139 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 2140 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 2141 sig_y.w[0] = y.w[0]; 2142 2143 // CHECK IF Y IS CANONICAL 2144 // 9999999999999999999999999999999999(decimal) = 2145 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 2146 // [0, 10^34) is the 754r supported canonical range. 2147 // If the value exceeds that, it is interpreted as 0. 2148 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 2149 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 2150 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 2151 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 2152 non_canon_y = 1; 2153 else 2154 non_canon_y = 0; 2155 2156 // ZERO (CASE4) 2157 // some properties: 2158 // (+ZERO == -ZERO) => therefore ignore the sign 2159 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 2160 // ignore the exponent field 2161 // (Any non-canonical # is considered 0) 2162 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 2163 x_is_zero = 1; 2164 } 2165 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 2166 y_is_zero = 1; 2167 } 2168 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 2169 if (x_is_zero && y_is_zero) { 2170 res = 1; 2171 BID_RETURN (res); 2172 } 2173 // is x is zero, it is greater if Y is negative 2174 else if (x_is_zero) { 2175 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2176 BID_RETURN (res); 2177 } 2178 // is y is zero, X is greater if it is positive 2179 else if (y_is_zero) { 2180 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2181 BID_RETURN (res); 2182 } 2183 // OPPOSITE SIGN (CASE5) 2184 // now, if the sign bits differ, x is greater if y is negative 2185 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 2186 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2187 BID_RETURN (res); 2188 } 2189 // REDUNDANT REPRESENTATIONS (CASE6) 2190 2191 // if exponents are the same, then we have a simple comparison 2192 // of the significands 2193 if (exp_y == exp_x) { 2194 res = (((sig_x.w[1] > sig_y.w[1]) 2195 || (sig_x.w[1] == sig_y.w[1] 2196 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) == 2197 MASK_SIGN)); 2198 BID_RETURN (res); 2199 } 2200 // if both components are either bigger or smaller, 2201 // it is clear what needs to be done 2202 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0] 2203 && exp_x > exp_y) { 2204 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2205 BID_RETURN (res); 2206 } 2207 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0] 2208 && exp_x < exp_y) { 2209 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 2210 BID_RETURN (res); 2211 } 2212 2213 diff = exp_x - exp_y; 2214 2215 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 2216 if (diff > 0) { // to simplify the loop below, 2217 2218 // if exp_x is 33 greater than exp_y, no need for compensation 2219 if (diff > 33) { 2220 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2221 BID_RETURN (res); 2222 } // difference cannot be greater than 10^33 2223 2224 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 2225 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 2226 2227 2228 // if postitive, return whichever significand is larger 2229 // (converse if negative) 2230 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 2231 && sig_n_prime256.w[1] == sig_y.w[1] 2232 && (sig_n_prime256.w[0] == sig_y.w[0])) { 2233 res = 1; 2234 BID_RETURN (res); 2235 } // if equal, return 1 2236 { 2237 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 2238 || (sig_n_prime256.w[1] > sig_y.w[1]) 2239 || (sig_n_prime256.w[1] == sig_y.w[1] 2240 && sig_n_prime256.w[0] > 2241 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 2242 BID_RETURN (res); 2243 } 2244 } 2245 //else { //128 by 64 bit multiply -> 192 bits 2246 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 2247 2248 // if postitive, return whichever significand is larger 2249 // (converse if negative) 2250 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 2251 && (sig_n_prime192.w[0] == sig_y.w[0])) { 2252 res = 1; 2253 BID_RETURN (res); 2254 } // if equal, return 1 2255 { 2256 res = (((sig_n_prime192.w[2] > 0) 2257 || (sig_n_prime192.w[1] > sig_y.w[1]) 2258 || (sig_n_prime192.w[1] == sig_y.w[1] 2259 && sig_n_prime192.w[0] > 2260 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 2261 BID_RETURN (res); 2262 } 2263 } 2264 2265 diff = exp_y - exp_x; 2266 2267 // if exp_x is 33 less than exp_y, no need for compensation 2268 if (diff > 33) { 2269 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 2270 BID_RETURN (res); 2271 } 2272 2273 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 2274 // adjust the y significand upwards 2275 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 2276 2277 2278 // if postitive, return whichever significand is larger 2279 // (converse if negative) 2280 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 2281 && sig_n_prime256.w[1] == sig_x.w[1] 2282 && (sig_n_prime256.w[0] == sig_x.w[0])) { 2283 res = 1; 2284 BID_RETURN (res); 2285 } // if equal, return 1 2286 { 2287 res = 2288 ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0 2289 && (sig_n_prime256.w[1] < sig_x.w[1] 2290 || (sig_n_prime256.w[1] == sig_x.w[1] 2291 && sig_n_prime256.w[0] < 2292 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 2293 BID_RETURN (res); 2294 } 2295 } 2296 //else { //128 by 64 bit multiply -> 192 bits 2297 // adjust the y significand upwards 2298 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 2299 2300 // if postitive, return whichever significand is larger 2301 // (converse if negative) 2302 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 2303 && (sig_n_prime192.w[0] == sig_x.w[0])) { 2304 res = 1; 2305 BID_RETURN (res); 2306 } // if equal, return 1 2307 { 2308 res = (sig_n_prime192.w[2] == 0 2309 && (sig_n_prime192.w[1] < sig_x.w[1] 2310 || (sig_n_prime192.w[1] == sig_x.w[1] 2311 && sig_n_prime192.w[0] < 2312 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2313 BID_RETURN (res); 2314 } 2315 } 2316 2317 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_ordered, x, 2318 y) 2319 2320 int res; 2321 2322 // NaN (CASE1) 2323 // if either number is NAN, the comparison is ordered : return 1 2324 if (((x.w[1] & MASK_NAN) == MASK_NAN) 2325 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 2326 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 2327 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 2328 *pfpsf |= INVALID_EXCEPTION; 2329 } 2330 { 2331 res = 0; 2332 BID_RETURN (res); 2333 } 2334 } 2335 { 2336 res = 1; 2337 BID_RETURN (res); 2338 } 2339 } 2340 2341 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_unordered, 2342 x, y) 2343 2344 int res; 2345 2346 // NaN (CASE1) 2347 // if either number is NAN, the comparison is unordered : return 1 2348 if (((x.w[1] & MASK_NAN) == MASK_NAN) 2349 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 2350 if ((x.w[1] & MASK_SNAN) == MASK_SNAN 2351 || (y.w[1] & MASK_SNAN) == MASK_SNAN) { 2352 *pfpsf |= INVALID_EXCEPTION; 2353 } 2354 { 2355 res = 1; 2356 BID_RETURN (res); 2357 } 2358 } 2359 { 2360 res = 0; 2361 BID_RETURN (res); 2362 } 2363 } 2364 2365 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_signaling_greater, 2366 x, y) 2367 2368 int res; 2369 int exp_x, exp_y; 2370 int diff; 2371 UINT128 sig_x, sig_y; 2372 UINT192 sig_n_prime192; 2373 UINT256 sig_n_prime256; 2374 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 2375 2376 // NaN (CASE1) 2377 // if either number is NAN, the comparison is unordered, 2378 // rather than equal : return 0 2379 if (((x.w[1] & MASK_NAN) == MASK_NAN) 2380 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 2381 *pfpsf |= INVALID_EXCEPTION; 2382 { 2383 res = 0; 2384 BID_RETURN (res); 2385 } 2386 } 2387 // SIMPLE (CASE2) 2388 // if all the bits are the same, these numbers are equal (not Greater). 2389 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 2390 res = 0; 2391 BID_RETURN (res); 2392 } 2393 // INFINITY (CASE3) 2394 if ((x.w[1] & MASK_INF) == MASK_INF) { 2395 // if x is neg infinity, there is no way it is greater than y, return 0 2396 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) { 2397 res = 0; 2398 BID_RETURN (res); 2399 } 2400 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity 2401 else { 2402 res = (((y.w[1] & MASK_INF) != MASK_INF) 2403 || ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 2404 BID_RETURN (res); 2405 } 2406 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 2407 // x is finite, so if y is positive infinity, then x is less, return 0 2408 // if y is negative infinity, then x is greater, return 1 2409 { 2410 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2411 BID_RETURN (res); 2412 } 2413 } 2414 // CONVERT X 2415 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 2416 sig_x.w[0] = x.w[0]; 2417 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 2418 2419 // CHECK IF X IS CANONICAL 2420 // 9999999999999999999999999999999999(decimal) = 2421 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 2422 // [0, 10^34) is the 754r supported canonical range. 2423 // If the value exceeds that, it is interpreted as 0. 2424 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 2425 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 2426 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 2427 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 2428 non_canon_x = 1; 2429 else 2430 non_canon_x = 0; 2431 2432 // CONVERT Y 2433 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 2434 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 2435 sig_y.w[0] = y.w[0]; 2436 2437 // CHECK IF Y IS CANONICAL 2438 // 9999999999999999999999999999999999(decimal) = 2439 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 2440 // [0, 10^34) is the 754r supported canonical range. 2441 // If the value exceeds that, it is interpreted as 0. 2442 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 2443 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 2444 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 2445 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 2446 non_canon_y = 1; 2447 else 2448 non_canon_y = 0; 2449 2450 // ZERO (CASE4) 2451 // some properties: 2452 // (+ZERO == -ZERO) => therefore ignore the sign 2453 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 2454 // ignore the exponent field 2455 // (Any non-canonical # is considered 0) 2456 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 2457 x_is_zero = 1; 2458 } 2459 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 2460 y_is_zero = 1; 2461 } 2462 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 2463 if (x_is_zero && y_is_zero) { 2464 res = 0; 2465 BID_RETURN (res); 2466 } 2467 // is x is zero, it is greater if Y is negative 2468 else if (x_is_zero) { 2469 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2470 BID_RETURN (res); 2471 } 2472 // is y is zero, X is greater if it is positive 2473 else if (y_is_zero) { 2474 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2475 BID_RETURN (res); 2476 } 2477 // OPPOSITE SIGN (CASE5) 2478 // now, if the sign bits differ, x is greater if y is negative 2479 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 2480 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2481 BID_RETURN (res); 2482 } 2483 // REDUNDANT REPRESENTATIONS (CASE6) 2484 // if exponents are the same, then we have a simple comparison 2485 // of the significands 2486 if (exp_y == exp_x) { 2487 res = (((sig_x.w[1] > sig_y.w[1]) 2488 || (sig_x.w[1] == sig_y.w[1] 2489 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) == 2490 MASK_SIGN)); 2491 BID_RETURN (res); 2492 } 2493 // if both components are either bigger or smaller, 2494 // it is clear what needs to be done 2495 if ((sig_x.w[1] > sig_y.w[1] 2496 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 2497 && exp_x >= exp_y) { 2498 { 2499 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2500 BID_RETURN (res); 2501 } 2502 } 2503 if ((sig_x.w[1] < sig_y.w[1] 2504 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 2505 && exp_x <= exp_y) { 2506 { 2507 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 2508 BID_RETURN (res); 2509 } 2510 } 2511 2512 diff = exp_x - exp_y; 2513 2514 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 2515 if (diff > 0) { // to simplify the loop below, 2516 2517 // if exp_x is 33 greater than exp_y, no need for compensation 2518 if (diff > 33) { 2519 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2520 BID_RETURN (res); 2521 } // difference cannot be greater than 10^33 2522 2523 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 2524 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 2525 2526 // if postitive, return whichever significand is larger 2527 // (converse if negative) 2528 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 2529 && sig_n_prime256.w[1] == sig_y.w[1] 2530 && (sig_n_prime256.w[0] == sig_y.w[0])) { 2531 res = 0; 2532 BID_RETURN (res); 2533 } // if equal, return 0 2534 { 2535 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 2536 || (sig_n_prime256.w[1] > sig_y.w[1]) 2537 || (sig_n_prime256.w[1] == sig_y.w[1] 2538 && sig_n_prime256.w[0] > 2539 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 2540 BID_RETURN (res); 2541 } 2542 } 2543 //else { //128 by 64 bit multiply -> 192 bits 2544 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x); 2545 2546 // if postitive, return whichever significand is larger 2547 // (converse if negative) 2548 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 2549 && (sig_n_prime192.w[0] == sig_y.w[0])) { 2550 res = 0; 2551 BID_RETURN (res); 2552 } // if equal, return 0 2553 { 2554 res = (((sig_n_prime192.w[2] > 0) 2555 || (sig_n_prime192.w[1] > sig_y.w[1]) 2556 || (sig_n_prime192.w[1] == sig_y.w[1] 2557 && sig_n_prime192.w[0] > 2558 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 2559 BID_RETURN (res); 2560 } 2561 } 2562 2563 diff = exp_y - exp_x; 2564 2565 // if exp_x is 33 less than exp_y, no need for compensation 2566 if (diff > 33) { 2567 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 2568 BID_RETURN (res); 2569 } 2570 2571 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 2572 // adjust the y significand upwards 2573 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 2574 2575 // if postitive, return whichever significand is larger 2576 // (converse if negative) 2577 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 2578 && sig_n_prime256.w[1] == sig_x.w[1] 2579 && (sig_n_prime256.w[0] == sig_x.w[0])) { 2580 res = 0; 2581 BID_RETURN (res); 2582 } // if equal, return 0 2583 { 2584 res = 2585 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 2586 || (sig_n_prime256.w[1] > sig_x.w[1] 2587 || (sig_n_prime256.w[1] == sig_x.w[1] 2588 && sig_n_prime256.w[0] > 2589 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) != MASK_SIGN)); 2590 BID_RETURN (res); 2591 } 2592 } 2593 //else { //128 by 64 bit multiply -> 192 bits 2594 // adjust the y significand upwards 2595 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y); 2596 2597 // if postitive, return whichever significand is larger 2598 // (converse if negative) 2599 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 2600 && (sig_n_prime192.w[0] == sig_x.w[0])) { 2601 res = 0; 2602 BID_RETURN (res); 2603 } // if equal, return 0 2604 { 2605 res = (sig_n_prime192.w[2] != 0 2606 || (sig_n_prime192.w[1] > sig_x.w[1] 2607 || (sig_n_prime192.w[1] == sig_x.w[1] 2608 && sig_n_prime192.w[0] > 2609 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN); 2610 BID_RETURN (res); 2611 } 2612 } 2613 2614 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, 2615 bid128_signaling_greater_equal, 2616 x, y) 2617 2618 int res; 2619 int exp_x, exp_y; 2620 int diff; 2621 UINT128 sig_x, sig_y; 2622 UINT192 sig_n_prime192; 2623 UINT256 sig_n_prime256; 2624 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 2625 2626 // NaN (CASE1) 2627 // if either number is NAN, the comparison is unordered, 2628 // rather than equal : return 1 2629 if (((x.w[1] & MASK_NAN) == MASK_NAN) 2630 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 2631 *pfpsf |= INVALID_EXCEPTION; 2632 { 2633 res = 0; 2634 BID_RETURN (res); 2635 } 2636 } 2637 // SIMPLE (CASE2) 2638 // if all the bits are the same, these numbers are equal (not Greater). 2639 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 2640 res = 1; 2641 BID_RETURN (res); 2642 } 2643 // INFINITY (CASE3) 2644 if ((x.w[1] & MASK_INF) == MASK_INF) { 2645 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } 2646 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) 2647 // x is -inf, so it is less than y unless y is -inf 2648 { 2649 res = (((y.w[1] & MASK_INF) == MASK_INF) 2650 && (y.w[1] & MASK_SIGN) == MASK_SIGN); 2651 BID_RETURN (res); 2652 } else 2653 // x is pos_inf, no way for it to be less than y 2654 { 2655 res = 1; 2656 BID_RETURN (res); 2657 } 2658 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 2659 // x is finite, so if y is positive infinity, then x is less, return 0 2660 // if y is negative infinity, then x is greater, return 1 2661 { 2662 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2663 BID_RETURN (res); 2664 } 2665 } 2666 // CONVERT X 2667 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 2668 sig_x.w[0] = x.w[0]; 2669 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 2670 2671 // CHECK IF X IS CANONICAL 2672 // 9999999999999999999999999999999999(decimal) = 2673 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 2674 // [0, 10^34) is the 754r supported canonical range. 2675 // If the value exceeds that, it is interpreted as 0. 2676 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 2677 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 2678 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 2679 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 2680 non_canon_x = 1; 2681 else 2682 non_canon_x = 0; 2683 2684 // CONVERT Y 2685 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 2686 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 2687 sig_y.w[0] = y.w[0]; 2688 2689 // CHECK IF Y IS CANONICAL 2690 // 9999999999999999999999999999999999(decimal) = 2691 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 2692 // [0, 10^34) is the 754r supported canonical range. 2693 // If the value exceeds that, it is interpreted as 0. 2694 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 2695 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 2696 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 2697 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 2698 non_canon_y = 1; 2699 else 2700 non_canon_y = 0; 2701 2702 // ZERO (CASE4) 2703 // some properties: 2704 // (+ZERO == -ZERO) => therefore ignore the sign 2705 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 2706 // ignore the exponent field 2707 // (Any non-canonical # is considered 0) 2708 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 2709 x_is_zero = 1; 2710 } 2711 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 2712 y_is_zero = 1; 2713 } 2714 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 2715 if (x_is_zero && y_is_zero) { 2716 res = 1; 2717 BID_RETURN (res); 2718 } 2719 // is x is zero, it is greater if Y is negative 2720 else if (x_is_zero) { 2721 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2722 BID_RETURN (res); 2723 } 2724 // is y is zero, X is greater if it is positive 2725 else if (y_is_zero) { 2726 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2727 BID_RETURN (res); 2728 } 2729 // OPPOSITE SIGN (CASE5) 2730 // now, if the sign bits differ, x is greater if y is negative 2731 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 2732 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2733 BID_RETURN (res); 2734 } 2735 // REDUNDANT REPRESENTATIONS (CASE6) 2736 // if exponents are the same, then we have a simple comparison 2737 // of the significands 2738 if (exp_y == exp_x) { 2739 res = (((sig_x.w[1] > sig_y.w[1]) 2740 || (sig_x.w[1] == sig_y.w[1] 2741 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) == 2742 MASK_SIGN)); 2743 BID_RETURN (res); 2744 } 2745 // if both components are either bigger or smaller, 2746 // it is clear what needs to be done 2747 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0] 2748 && exp_x > exp_y) { 2749 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2750 BID_RETURN (res); 2751 } 2752 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0] 2753 && exp_x < exp_y) { 2754 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 2755 BID_RETURN (res); 2756 } 2757 2758 diff = exp_x - exp_y; 2759 2760 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 2761 if (diff > 0) { // to simplify the loop below, 2762 2763 // if exp_x is 33 greater than exp_y, no need for compensation 2764 if (diff > 33) { 2765 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2766 BID_RETURN (res); 2767 } // difference cannot be greater than 10^33 2768 2769 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 2770 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 2771 2772 2773 // if postitive, return whichever significand is larger 2774 // (converse if negative) 2775 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 2776 && sig_n_prime256.w[1] == sig_y.w[1] 2777 && (sig_n_prime256.w[0] == sig_y.w[0])) { 2778 res = 1; 2779 BID_RETURN (res); 2780 } // if equal, return 1 2781 { 2782 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 2783 || (sig_n_prime256.w[1] > sig_y.w[1]) 2784 || (sig_n_prime256.w[1] == sig_y.w[1] 2785 && sig_n_prime256.w[0] > 2786 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 2787 BID_RETURN (res); 2788 } 2789 } 2790 //else { //128 by 64 bit multiply -> 192 bits 2791 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 2792 2793 // if postitive, return whichever significand is larger 2794 // (converse if negative) 2795 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 2796 && (sig_n_prime192.w[0] == sig_y.w[0])) { 2797 res = 1; 2798 BID_RETURN (res); 2799 } // if equal, return 1 2800 { 2801 res = (((sig_n_prime192.w[2] > 0) 2802 || (sig_n_prime192.w[1] > sig_y.w[1]) 2803 || (sig_n_prime192.w[1] == sig_y.w[1] 2804 && sig_n_prime192.w[0] > 2805 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 2806 BID_RETURN (res); 2807 } 2808 } 2809 2810 diff = exp_y - exp_x; 2811 2812 // if exp_x is 33 less than exp_y, no need for compensation 2813 if (diff > 33) { 2814 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 2815 BID_RETURN (res); 2816 } 2817 2818 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 2819 // adjust the y significand upwards 2820 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 2821 2822 2823 // if postitive, return whichever significand is larger 2824 // (converse if negative) 2825 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 2826 && sig_n_prime256.w[1] == sig_x.w[1] 2827 && (sig_n_prime256.w[0] == sig_x.w[0])) { 2828 res = 1; 2829 BID_RETURN (res); 2830 } // if equal, return 1 2831 { 2832 res = 2833 ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0 2834 && (sig_n_prime256.w[1] < sig_x.w[1] 2835 || (sig_n_prime256.w[1] == sig_x.w[1] 2836 && sig_n_prime256.w[0] < 2837 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 2838 BID_RETURN (res); 2839 } 2840 } 2841 //else { //128 by 64 bit multiply -> 192 bits 2842 // adjust the y significand upwards 2843 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 2844 2845 // if postitive, return whichever significand is larger 2846 // (converse if negative) 2847 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 2848 && (sig_n_prime192.w[0] == sig_x.w[0])) { 2849 res = 1; 2850 BID_RETURN (res); 2851 } // if equal, return 1 2852 { 2853 res = (sig_n_prime192.w[2] == 0 2854 && (sig_n_prime192.w[1] < sig_x.w[1] 2855 || (sig_n_prime192.w[1] == sig_x.w[1] 2856 && sig_n_prime192.w[0] < 2857 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2858 BID_RETURN (res); 2859 } 2860 } 2861 2862 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, 2863 bid128_signaling_greater_unordered, 2864 x, y) 2865 2866 int res; 2867 int exp_x, exp_y; 2868 int diff; 2869 UINT128 sig_x, sig_y; 2870 UINT192 sig_n_prime192; 2871 UINT256 sig_n_prime256; 2872 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 2873 2874 // NaN (CASE1) 2875 // if either number is NAN, the comparison is unordered, 2876 // rather than equal : return 1 2877 if (((x.w[1] & MASK_NAN) == MASK_NAN) 2878 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 2879 *pfpsf |= INVALID_EXCEPTION; 2880 { 2881 res = 1; 2882 BID_RETURN (res); 2883 } 2884 } 2885 // SIMPLE (CASE2) 2886 // if all the bits are the same, these numbers are equal (not Greater). 2887 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 2888 res = 0; 2889 BID_RETURN (res); 2890 } 2891 // INFINITY (CASE3) 2892 if ((x.w[1] & MASK_INF) == MASK_INF) { 2893 // if x is neg infinity, there is no way it is greater than y, return 0 2894 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) { 2895 res = 0; 2896 BID_RETURN (res); 2897 } 2898 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity 2899 else { 2900 res = (((y.w[1] & MASK_INF) != MASK_INF) 2901 || ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 2902 BID_RETURN (res); 2903 } 2904 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 2905 // x is finite, so if y is positive infinity, then x is less, return 0 2906 // if y is negative infinity, then x is greater, return 1 2907 { 2908 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2909 BID_RETURN (res); 2910 } 2911 } 2912 // CONVERT X 2913 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 2914 sig_x.w[0] = x.w[0]; 2915 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 2916 2917 // CHECK IF X IS CANONICAL 2918 // 9999999999999999999999999999999999(decimal) = 2919 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 2920 // [0, 10^34) is the 754r supported canonical range. 2921 // If the value exceeds that, it is interpreted as 0. 2922 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 2923 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 2924 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 2925 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 2926 non_canon_x = 1; 2927 else 2928 non_canon_x = 0; 2929 2930 // CONVERT Y 2931 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 2932 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 2933 sig_y.w[0] = y.w[0]; 2934 2935 // CHECK IF Y IS CANONICAL 2936 // 9999999999999999999999999999999999(decimal) = 2937 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 2938 // [0, 10^34) is the 754r supported canonical range. 2939 // If the value exceeds that, it is interpreted as 0. 2940 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 2941 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 2942 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 2943 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 2944 non_canon_y = 1; 2945 else 2946 non_canon_y = 0; 2947 2948 // ZERO (CASE4) 2949 // some properties: 2950 // (+ZERO == -ZERO) => therefore ignore the sign 2951 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 2952 // ignore the exponent field 2953 // (Any non-canonical # is considered 0) 2954 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 2955 x_is_zero = 1; 2956 } 2957 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 2958 y_is_zero = 1; 2959 } 2960 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 2961 if (x_is_zero && y_is_zero) { 2962 res = 0; 2963 BID_RETURN (res); 2964 } 2965 // is x is zero, it is greater if Y is negative 2966 else if (x_is_zero) { 2967 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2968 BID_RETURN (res); 2969 } 2970 // is y is zero, X is greater if it is positive 2971 else if (y_is_zero) { 2972 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2973 BID_RETURN (res); 2974 } 2975 // OPPOSITE SIGN (CASE5) 2976 // now, if the sign bits differ, x is greater if y is negative 2977 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 2978 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 2979 BID_RETURN (res); 2980 } 2981 // REDUNDANT REPRESENTATIONS (CASE6) 2982 // if exponents are the same, then we have a simple comparison 2983 // of the significands 2984 if (exp_y == exp_x) { 2985 res = (((sig_x.w[1] > sig_y.w[1]) 2986 || (sig_x.w[1] == sig_y.w[1] 2987 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) == 2988 MASK_SIGN)); 2989 BID_RETURN (res); 2990 } 2991 // if both components are either bigger or smaller, 2992 // it is clear what needs to be done 2993 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0] 2994 && exp_x > exp_y) { 2995 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2996 BID_RETURN (res); 2997 } 2998 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0] 2999 && exp_x < exp_y) { 3000 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3001 BID_RETURN (res); 3002 } 3003 3004 diff = exp_x - exp_y; 3005 3006 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 3007 if (diff > 0) { // to simplify the loop below, 3008 3009 // if exp_x is 33 greater than exp_y, no need for compensation 3010 if (diff > 33) { 3011 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3012 BID_RETURN (res); 3013 } // difference cannot be greater than 10^33 3014 3015 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 3016 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 3017 3018 3019 // if postitive, return whichever significand is larger 3020 // (converse if negative) 3021 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 3022 && sig_n_prime256.w[1] == sig_y.w[1] 3023 && (sig_n_prime256.w[0] == sig_y.w[0])) { 3024 res = 0; 3025 BID_RETURN (res); 3026 } // if equal, return 0 3027 { 3028 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 3029 || (sig_n_prime256.w[1] > sig_y.w[1]) 3030 || (sig_n_prime256.w[1] == sig_y.w[1] 3031 && sig_n_prime256.w[0] > 3032 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 3033 BID_RETURN (res); 3034 } 3035 } 3036 //else { //128 by 64 bit multiply -> 192 bits 3037 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 3038 3039 // if postitive, return whichever significand is larger 3040 // (converse if negative) 3041 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 3042 && (sig_n_prime192.w[0] == sig_y.w[0])) { 3043 res = 0; 3044 BID_RETURN (res); 3045 } // if equal, return 0 3046 { 3047 res = (((sig_n_prime192.w[2] > 0) 3048 || (sig_n_prime192.w[1] > sig_y.w[1]) 3049 || (sig_n_prime192.w[1] == sig_y.w[1] 3050 && sig_n_prime192.w[0] > 3051 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 3052 BID_RETURN (res); 3053 } 3054 } 3055 3056 diff = exp_y - exp_x; 3057 3058 // if exp_x is 33 less than exp_y, no need for compensation 3059 if (diff > 33) { 3060 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3061 BID_RETURN (res); 3062 } 3063 3064 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 3065 // adjust the y significand upwards 3066 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 3067 3068 3069 // if postitive, return whichever significand is larger 3070 // (converse if negative) 3071 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 3072 && sig_n_prime256.w[1] == sig_x.w[1] 3073 && (sig_n_prime256.w[0] == sig_x.w[0])) { 3074 res = 0; 3075 BID_RETURN (res); 3076 } // if equal, return 0 3077 { 3078 res = 3079 ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0 3080 && (sig_n_prime256.w[1] < sig_x.w[1] 3081 || (sig_n_prime256.w[1] == sig_x.w[1] 3082 && sig_n_prime256.w[0] < 3083 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 3084 BID_RETURN (res); 3085 } 3086 } 3087 //else { //128 by 64 bit multiply -> 192 bits 3088 // adjust the y significand upwards 3089 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 3090 3091 // if postitive, return whichever significand is larger 3092 // (converse if negative) 3093 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 3094 && (sig_n_prime192.w[0] == sig_x.w[0])) { 3095 res = 0; 3096 BID_RETURN (res); 3097 } // if equal, return 0 3098 { 3099 res = (sig_n_prime192.w[2] == 0 3100 && (sig_n_prime192.w[1] < sig_x.w[1] 3101 || (sig_n_prime192.w[1] == sig_x.w[1] 3102 && sig_n_prime192.w[0] < 3103 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 3104 BID_RETURN (res); 3105 } 3106 } 3107 3108 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_signaling_less, x, 3109 y) 3110 3111 int res; 3112 int exp_x, exp_y; 3113 int diff; 3114 UINT128 sig_x, sig_y; 3115 UINT192 sig_n_prime192; 3116 UINT256 sig_n_prime256; 3117 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 3118 3119 // NaN (CASE1) 3120 // if either number is NAN, the comparison is unordered, 3121 // rather than equal : return 0 3122 if (((x.w[1] & MASK_NAN) == MASK_NAN) 3123 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 3124 *pfpsf |= INVALID_EXCEPTION; 3125 { 3126 res = 0; 3127 BID_RETURN (res); 3128 } 3129 } 3130 // SIMPLE (CASE2) 3131 // if all the bits are the same, these numbers are equal. 3132 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 3133 res = 0; 3134 BID_RETURN (res); 3135 } 3136 // INFINITY (CASE3) 3137 if ((x.w[1] & MASK_INF) == MASK_INF) { 3138 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } 3139 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) 3140 // x is -inf, so it is less than y unless y is -inf 3141 { 3142 res = (((y.w[1] & MASK_INF) != MASK_INF) 3143 || (y.w[1] & MASK_SIGN) != MASK_SIGN); 3144 BID_RETURN (res); 3145 } else 3146 // x is pos_inf, no way for it to be less than y 3147 { 3148 res = 0; 3149 BID_RETURN (res); 3150 } 3151 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 3152 // x is finite, so if y is positive infinity, then x is less, return 0 3153 // if y is negative infinity, then x is greater, return 1 3154 { 3155 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3156 BID_RETURN (res); 3157 } 3158 } 3159 // CONVERT X 3160 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 3161 sig_x.w[0] = x.w[0]; 3162 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 3163 3164 // CHECK IF X IS CANONICAL 3165 // 9999999999999999999999999999999999(decimal) = 3166 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 3167 // [0, 10^34) is the 754r supported canonical range. 3168 // If the value exceeds that, it is interpreted as 0. 3169 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 3170 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 3171 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 3172 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 3173 non_canon_x = 1; 3174 else 3175 non_canon_x = 0; 3176 3177 // CONVERT Y 3178 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 3179 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 3180 sig_y.w[0] = y.w[0]; 3181 3182 // CHECK IF Y IS CANONICAL 3183 // 9999999999999999999999999999999999(decimal) = 3184 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 3185 // [0, 10^34) is the 754r supported canonical range. 3186 // If the value exceeds that, it is interpreted as 0. 3187 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 3188 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 3189 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 3190 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 3191 non_canon_y = 1; 3192 else 3193 non_canon_y = 0; 3194 3195 // ZERO (CASE4) 3196 // some properties: 3197 // (+ZERO == -ZERO) => therefore ignore the sign 3198 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 3199 // ignore the exponent field 3200 // (Any non-canonical # is considered 0) 3201 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 3202 x_is_zero = 1; 3203 } 3204 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 3205 y_is_zero = 1; 3206 } 3207 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 3208 if (x_is_zero && y_is_zero) { 3209 res = 0; 3210 BID_RETURN (res); 3211 } 3212 // is x is zero, it is greater if Y is negative 3213 else if (x_is_zero) { 3214 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3215 BID_RETURN (res); 3216 } 3217 // is y is zero, X is greater if it is positive 3218 else if (y_is_zero) { 3219 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3220 BID_RETURN (res); 3221 } 3222 // OPPOSITE SIGN (CASE5) 3223 // now, if the sign bits differ, x is greater if y is negative 3224 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 3225 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3226 BID_RETURN (res); 3227 } 3228 // REDUNDANT REPRESENTATIONS (CASE6) 3229 // if exponents are the same, then we have a simple comparison 3230 // of the significands 3231 if (exp_y == exp_x) { 3232 res = (((sig_x.w[1] > sig_y.w[1]) 3233 || (sig_x.w[1] == sig_y.w[1] 3234 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) != 3235 MASK_SIGN)); 3236 BID_RETURN (res); 3237 } 3238 // if both components are either bigger or smaller, 3239 // it is clear what needs to be done 3240 if ((sig_x.w[1] > sig_y.w[1] 3241 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 3242 && exp_x >= exp_y) { 3243 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3244 BID_RETURN (res); 3245 } 3246 if ((sig_x.w[1] < sig_y.w[1] 3247 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 3248 && exp_x <= exp_y) { 3249 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3250 BID_RETURN (res); 3251 } 3252 3253 diff = exp_x - exp_y; 3254 3255 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 3256 if (diff > 0) { // to simplify the loop below, 3257 3258 // if exp_x is 33 greater than exp_y, no need for compensation 3259 if (diff > 33) { 3260 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3261 BID_RETURN (res); 3262 } // difference cannot be greater than 10^33 3263 3264 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 3265 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 3266 3267 3268 // if postitive, return whichever significand is larger 3269 // (converse if negative) 3270 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 3271 && sig_n_prime256.w[1] == sig_y.w[1] 3272 && (sig_n_prime256.w[0] == sig_y.w[0])) { 3273 res = 0; 3274 BID_RETURN (res); 3275 } // if equal, return 0 3276 { 3277 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 3278 || (sig_n_prime256.w[1] > sig_y.w[1]) 3279 || (sig_n_prime256.w[1] == sig_y.w[1] 3280 && sig_n_prime256.w[0] > 3281 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 3282 BID_RETURN (res); 3283 } 3284 } 3285 //else { //128 by 64 bit multiply -> 192 bits 3286 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 3287 3288 // if postitive, return whichever significand is larger 3289 // (converse if negative) 3290 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 3291 && (sig_n_prime192.w[0] == sig_y.w[0])) { 3292 res = 0; 3293 BID_RETURN (res); 3294 } // if equal, return 0 3295 { 3296 res = (((sig_n_prime192.w[2] > 0) 3297 || (sig_n_prime192.w[1] > sig_y.w[1]) 3298 || (sig_n_prime192.w[1] == sig_y.w[1] 3299 && sig_n_prime192.w[0] > 3300 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 3301 BID_RETURN (res); 3302 } 3303 } 3304 3305 diff = exp_y - exp_x; 3306 3307 // if exp_x is 33 less than exp_y, |x| < |y|, return 1 if positive 3308 if (diff > 33) { 3309 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3310 BID_RETURN (res); 3311 } 3312 3313 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 3314 // adjust the y significand upwards 3315 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 3316 3317 3318 // if postitive, return whichever significand is larger 3319 // (converse if negative) 3320 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 3321 && sig_n_prime256.w[1] == sig_x.w[1] 3322 && (sig_n_prime256.w[0] == sig_x.w[0])) { 3323 res = 0; 3324 BID_RETURN (res); 3325 } // if equal, return 1 3326 { 3327 res = 3328 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 3329 || (sig_n_prime256.w[1] > sig_x.w[1] 3330 || (sig_n_prime256.w[1] == sig_x.w[1] 3331 && sig_n_prime256.w[0] > 3332 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 3333 BID_RETURN (res); 3334 } 3335 } 3336 //else { //128 by 64 bit multiply -> 192 bits 3337 // adjust the y significand upwards 3338 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 3339 3340 // if postitive, return whichever significand is larger 3341 // (converse if negative) 3342 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 3343 && (sig_n_prime192.w[0] == sig_x.w[0])) { 3344 res = 0; 3345 BID_RETURN (res); 3346 } // if equal, return 0 3347 { 3348 res = (sig_n_prime192.w[2] != 0 3349 || (sig_n_prime192.w[1] > sig_x.w[1] 3350 || (sig_n_prime192.w[1] == sig_x.w[1] 3351 && sig_n_prime192.w[0] > 3352 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 3353 BID_RETURN (res); 3354 } 3355 } 3356 3357 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, 3358 bid128_signaling_less_equal, 3359 x, y) 3360 3361 int res; 3362 int exp_x, exp_y; 3363 int diff; 3364 UINT128 sig_x, sig_y; 3365 UINT192 sig_n_prime192; 3366 UINT256 sig_n_prime256; 3367 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 3368 3369 // NaN (CASE1) 3370 // if either number is NAN, the comparison is unordered, 3371 // rather than equal : return 0 3372 if (((x.w[1] & MASK_NAN) == MASK_NAN) 3373 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 3374 *pfpsf |= INVALID_EXCEPTION; 3375 { 3376 res = 0; 3377 BID_RETURN (res); 3378 } 3379 } 3380 // SIMPLE (CASE2) 3381 // if all the bits are the same, these numbers are equal (not Greater). 3382 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 3383 res = 1; 3384 BID_RETURN (res); 3385 } 3386 // INFINITY (CASE3) 3387 if ((x.w[1] & MASK_INF) == MASK_INF) { 3388 // if x is neg infinity, there is no way it is greater than y, return 1 3389 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) { 3390 res = 1; 3391 BID_RETURN (res); 3392 } 3393 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity 3394 else { 3395 res = (((y.w[1] & MASK_INF) == MASK_INF) 3396 && ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 3397 BID_RETURN (res); 3398 } 3399 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 3400 // x is finite, so if y is positive infinity, then x is less, return 0 3401 // if y is negative infinity, then x is greater, return 1 3402 { 3403 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3404 BID_RETURN (res); 3405 } 3406 } 3407 // CONVERT X 3408 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 3409 sig_x.w[0] = x.w[0]; 3410 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 3411 3412 // CHECK IF X IS CANONICAL 3413 // 9999999999999999999999999999999999(decimal) = 3414 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 3415 // [0, 10^34) is the 754r supported canonical range. 3416 // If the value exceeds that, it is interpreted as 0. 3417 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 3418 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 3419 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 3420 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 3421 non_canon_x = 1; 3422 else 3423 non_canon_x = 0; 3424 3425 // CONVERT Y 3426 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 3427 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 3428 sig_y.w[0] = y.w[0]; 3429 3430 // CHECK IF Y IS CANONICAL 3431 // 9999999999999999999999999999999999(decimal) = 3432 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 3433 // [0, 10^34) is the 754r supported canonical range. 3434 // If the value exceeds that, it is interpreted as 0. 3435 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 3436 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 3437 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 3438 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 3439 non_canon_y = 1; 3440 else 3441 non_canon_y = 0; 3442 3443 // ZERO (CASE4) 3444 // some properties: 3445 // (+ZERO == -ZERO) => therefore ignore the sign 3446 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 3447 // ignore the exponent field 3448 // (Any non-canonical # is considered 0) 3449 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 3450 x_is_zero = 1; 3451 } 3452 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 3453 y_is_zero = 1; 3454 } 3455 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 3456 if (x_is_zero && y_is_zero) { 3457 res = 1; 3458 BID_RETURN (res); 3459 } 3460 // is x is zero, it is greater if Y is negative 3461 else if (x_is_zero) { 3462 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3463 BID_RETURN (res); 3464 } 3465 // is y is zero, X is greater if it is positive 3466 else if (y_is_zero) { 3467 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3468 BID_RETURN (res); 3469 } 3470 // OPPOSITE SIGN (CASE5) 3471 // now, if the sign bits differ, x is greater if y is negative 3472 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 3473 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3474 BID_RETURN (res); 3475 } 3476 // REDUNDANT REPRESENTATIONS (CASE6) 3477 // if exponents are the same, then we have a simple comparison 3478 // of the significands 3479 if (exp_y == exp_x) { 3480 res = (((sig_x.w[1] > sig_y.w[1]) 3481 || (sig_x.w[1] == sig_y.w[1] 3482 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) != 3483 MASK_SIGN)); 3484 BID_RETURN (res); 3485 } 3486 // if both components are either bigger or smaller, 3487 // it is clear what needs to be done 3488 if ((sig_x.w[1] > sig_y.w[1] 3489 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 3490 && exp_x >= exp_y) { 3491 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3492 BID_RETURN (res); 3493 } 3494 if ((sig_x.w[1] < sig_y.w[1] 3495 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 3496 && exp_x <= exp_y) { 3497 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3498 BID_RETURN (res); 3499 } 3500 3501 diff = exp_x - exp_y; 3502 3503 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 3504 if (diff > 0) { // to simplify the loop below, 3505 3506 // if exp_x is 33 greater than exp_y, no need for compensation 3507 if (diff > 33) { 3508 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3509 BID_RETURN (res); 3510 } // difference cannot be greater than 10^33 3511 3512 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 3513 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 3514 3515 3516 // if postitive, return whichever significand is larger 3517 // (converse if negative) 3518 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 3519 && sig_n_prime256.w[1] == sig_y.w[1] 3520 && (sig_n_prime256.w[0] == sig_y.w[0])) { 3521 res = 1; 3522 BID_RETURN (res); 3523 } // if equal, return 0 3524 { 3525 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 3526 || (sig_n_prime256.w[1] > sig_y.w[1]) 3527 || (sig_n_prime256.w[1] == sig_y.w[1] 3528 && sig_n_prime256.w[0] > 3529 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 3530 BID_RETURN (res); 3531 } 3532 } 3533 //else { //128 by 64 bit multiply -> 192 bits 3534 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 3535 3536 // if postitive, return whichever significand is larger 3537 // (converse if negative) 3538 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 3539 && (sig_n_prime192.w[0] == sig_y.w[0])) { 3540 res = 1; 3541 BID_RETURN (res); 3542 } // if equal, return 0 3543 { 3544 res = (((sig_n_prime192.w[2] > 0) 3545 || (sig_n_prime192.w[1] > sig_y.w[1]) 3546 || (sig_n_prime192.w[1] == sig_y.w[1] 3547 && sig_n_prime192.w[0] > 3548 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 3549 BID_RETURN (res); 3550 } 3551 } 3552 3553 diff = exp_y - exp_x; 3554 3555 // if exp_x is 33 less than exp_y, no need for compensation 3556 if (diff > 33) { 3557 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3558 BID_RETURN (res); 3559 } 3560 3561 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 3562 // adjust the y significand upwards 3563 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 3564 3565 3566 // if postitive, return whichever significand is larger 3567 // (converse if negative) 3568 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 3569 && sig_n_prime256.w[1] == sig_x.w[1] 3570 && (sig_n_prime256.w[0] == sig_x.w[0])) { 3571 res = 1; 3572 BID_RETURN (res); 3573 } // if equal, return 0 3574 { 3575 res = 3576 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 3577 || (sig_n_prime256.w[1] > sig_x.w[1] 3578 || (sig_n_prime256.w[1] == sig_x.w[1] 3579 && sig_n_prime256.w[0] > 3580 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 3581 BID_RETURN (res); 3582 } 3583 } 3584 //else { //128 by 64 bit multiply -> 192 bits 3585 // adjust the y significand upwards 3586 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 3587 3588 // if postitive, return whichever significand is larger 3589 // (converse if negative) 3590 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 3591 && (sig_n_prime192.w[0] == sig_x.w[0])) { 3592 res = 1; 3593 BID_RETURN (res); 3594 } // if equal, return 0 3595 { 3596 res = (sig_n_prime192.w[2] != 0 3597 || (sig_n_prime192.w[1] > sig_x.w[1] 3598 || (sig_n_prime192.w[1] == sig_x.w[1] 3599 && sig_n_prime192.w[0] > 3600 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 3601 BID_RETURN (res); 3602 } 3603 } 3604 3605 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, 3606 bid128_signaling_less_unordered, 3607 x, y) 3608 3609 int res; 3610 int exp_x, exp_y; 3611 int diff; 3612 UINT128 sig_x, sig_y; 3613 UINT192 sig_n_prime192; 3614 UINT256 sig_n_prime256; 3615 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 3616 3617 // NaN (CASE1) 3618 // if either number is NAN, the comparison is unordered 3619 if (((x.w[1] & MASK_NAN) == MASK_NAN) 3620 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 3621 *pfpsf |= INVALID_EXCEPTION; 3622 { 3623 res = 1; 3624 BID_RETURN (res); 3625 } 3626 } 3627 // SIMPLE (CASE2) 3628 // if all the bits are the same, these numbers are equal. 3629 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 3630 res = 0; 3631 BID_RETURN (res); 3632 } 3633 // INFINITY (CASE3) 3634 if ((x.w[1] & MASK_INF) == MASK_INF) { 3635 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } 3636 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) 3637 // x is -inf, so it is less than y unless y is -inf 3638 { 3639 res = (((y.w[1] & MASK_INF) != MASK_INF) 3640 || (y.w[1] & MASK_SIGN) != MASK_SIGN); 3641 BID_RETURN (res); 3642 } else 3643 // x is pos_inf, no way for it to be less than y 3644 { 3645 res = 0; 3646 BID_RETURN (res); 3647 } 3648 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 3649 // x is finite, so if y is positive infinity, then x is less, return 0 3650 // if y is negative infinity, then x is greater, return 1 3651 { 3652 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3653 BID_RETURN (res); 3654 } 3655 } 3656 // CONVERT X 3657 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 3658 sig_x.w[0] = x.w[0]; 3659 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 3660 3661 // CHECK IF X IS CANONICAL 3662 // 9999999999999999999999999999999999(decimal) = 3663 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 3664 // [0, 10^34) is the 754r supported canonical range. 3665 // If the value exceeds that, it is interpreted as 0. 3666 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 3667 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 3668 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 3669 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 3670 non_canon_x = 1; 3671 else 3672 non_canon_x = 0; 3673 3674 // CONVERT Y 3675 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 3676 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 3677 sig_y.w[0] = y.w[0]; 3678 3679 // CHECK IF Y IS CANONICAL 3680 // 9999999999999999999999999999999999(decimal) = 3681 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 3682 // [0, 10^34) is the 754r supported canonical range. 3683 // If the value exceeds that, it is interpreted as 0. 3684 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 3685 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 3686 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 3687 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 3688 non_canon_y = 1; 3689 else 3690 non_canon_y = 0; 3691 3692 // ZERO (CASE4) 3693 // some properties: 3694 // (+ZERO == -ZERO) => therefore ignore the sign 3695 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 3696 // ignore the exponent field 3697 // (Any non-canonical # is considered 0) 3698 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 3699 x_is_zero = 1; 3700 } 3701 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 3702 y_is_zero = 1; 3703 } 3704 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 3705 if (x_is_zero && y_is_zero) { 3706 res = 0; 3707 BID_RETURN (res); 3708 } 3709 // is x is zero, it is greater if Y is negative 3710 else if (x_is_zero) { 3711 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3712 BID_RETURN (res); 3713 } 3714 // is y is zero, X is greater if it is positive 3715 else if (y_is_zero) { 3716 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3717 BID_RETURN (res); 3718 } 3719 // OPPOSITE SIGN (CASE5) 3720 // now, if the sign bits differ, x is greater if y is negative 3721 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 3722 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3723 BID_RETURN (res); 3724 } 3725 // REDUNDANT REPRESENTATIONS (CASE6) 3726 // if exponents are the same, then we have a simple comparison 3727 // of the significands 3728 if (exp_y == exp_x) { 3729 res = (((sig_x.w[1] > sig_y.w[1]) 3730 || (sig_x.w[1] == sig_y.w[1] 3731 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) != 3732 MASK_SIGN)); 3733 BID_RETURN (res); 3734 } 3735 // if both components are either bigger or smaller, 3736 // it is clear what needs to be done 3737 if ((sig_x.w[1] > sig_y.w[1] 3738 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 3739 && exp_x >= exp_y) { 3740 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3741 BID_RETURN (res); 3742 } 3743 if ((sig_x.w[1] < sig_y.w[1] 3744 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 3745 && exp_x <= exp_y) { 3746 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3747 BID_RETURN (res); 3748 } 3749 3750 diff = exp_x - exp_y; 3751 3752 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 3753 if (diff > 0) { // to simplify the loop below, 3754 3755 // if exp_x is 33 greater than exp_y, no need for compensation 3756 if (diff > 33) { 3757 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3758 BID_RETURN (res); 3759 } // difference cannot be greater than 10^33 3760 3761 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 3762 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 3763 3764 3765 // if postitive, return whichever significand is larger 3766 // (converse if negative) 3767 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 3768 && sig_n_prime256.w[1] == sig_y.w[1] 3769 && (sig_n_prime256.w[0] == sig_y.w[0])) { 3770 res = 0; 3771 BID_RETURN (res); 3772 } // if equal, return 0 3773 { 3774 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 3775 || (sig_n_prime256.w[1] > sig_y.w[1]) 3776 || (sig_n_prime256.w[1] == sig_y.w[1] 3777 && sig_n_prime256.w[0] > 3778 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 3779 BID_RETURN (res); 3780 } 3781 } 3782 //else { //128 by 64 bit multiply -> 192 bits 3783 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 3784 3785 // if postitive, return whichever significand is larger 3786 // (converse if negative) 3787 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 3788 && (sig_n_prime192.w[0] == sig_y.w[0])) { 3789 res = 0; 3790 BID_RETURN (res); 3791 } // if equal, return 0 3792 { 3793 res = (((sig_n_prime192.w[2] > 0) 3794 || (sig_n_prime192.w[1] > sig_y.w[1]) 3795 || (sig_n_prime192.w[1] == sig_y.w[1] 3796 && sig_n_prime192.w[0] > 3797 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 3798 BID_RETURN (res); 3799 } 3800 } 3801 3802 diff = exp_y - exp_x; 3803 3804 // if exp_x is 33 less than exp_y, no need for compensation 3805 if (diff > 33) { 3806 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3807 BID_RETURN (res); 3808 } 3809 3810 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 3811 // adjust the y significand upwards 3812 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 3813 3814 3815 // if postitive, return whichever significand is larger 3816 // (converse if negative) 3817 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 3818 && sig_n_prime256.w[1] == sig_x.w[1] 3819 && (sig_n_prime256.w[0] == sig_x.w[0])) { 3820 res = 0; 3821 BID_RETURN (res); 3822 } // if equal, return 1 3823 { 3824 res = 3825 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 3826 || (sig_n_prime256.w[1] > sig_x.w[1] 3827 || (sig_n_prime256.w[1] == sig_x.w[1] 3828 && sig_n_prime256.w[0] > 3829 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 3830 BID_RETURN (res); 3831 } 3832 } 3833 //else { //128 by 64 bit multiply -> 192 bits 3834 // adjust the y significand upwards 3835 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 3836 3837 // if postitive, return whichever significand is larger (converse if negative) 3838 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 3839 && (sig_n_prime192.w[0] == sig_x.w[0])) { 3840 res = 0; 3841 BID_RETURN (res); 3842 } // if equal, return 0 3843 { 3844 res = (sig_n_prime192.w[2] != 0 3845 || (sig_n_prime192.w[1] > sig_x.w[1] 3846 || (sig_n_prime192.w[1] == sig_x.w[1] 3847 && sig_n_prime192.w[0] > 3848 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 3849 BID_RETURN (res); 3850 } 3851 } 3852 3853 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, 3854 bid128_signaling_not_greater, 3855 x, y) 3856 3857 int res; 3858 int exp_x, exp_y; 3859 int diff; 3860 UINT128 sig_x, sig_y; 3861 UINT192 sig_n_prime192; 3862 UINT256 sig_n_prime256; 3863 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 3864 3865 // NaN (CASE1) 3866 // if either number is NAN, the comparison is unordered, 3867 // rather than equal : return 0 3868 if (((x.w[1] & MASK_NAN) == MASK_NAN) 3869 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 3870 *pfpsf |= INVALID_EXCEPTION; 3871 { 3872 res = 1; 3873 BID_RETURN (res); 3874 } 3875 } 3876 // SIMPLE (CASE2) 3877 // if all the bits are the same, these numbers are equal (not Greater). 3878 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 3879 res = 1; 3880 BID_RETURN (res); 3881 } 3882 // INFINITY (CASE3) 3883 if ((x.w[1] & MASK_INF) == MASK_INF) { 3884 // if x is neg infinity, there is no way it is greater than y, return 1 3885 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) { 3886 res = 1; 3887 BID_RETURN (res); 3888 } 3889 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity 3890 else { 3891 res = (((y.w[1] & MASK_INF) == MASK_INF) 3892 && ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 3893 BID_RETURN (res); 3894 } 3895 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 3896 // x is finite, so if y is positive infinity, then x is less, return 0 3897 // if y is negative infinity, then x is greater, return 1 3898 { 3899 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3900 BID_RETURN (res); 3901 } 3902 } 3903 // CONVERT X 3904 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 3905 sig_x.w[0] = x.w[0]; 3906 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 3907 3908 // CHECK IF X IS CANONICAL 3909 // 9999999999999999999999999999999999(decimal) = 3910 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 3911 // [0, 10^34) is the 754r supported canonical range. 3912 // If the value exceeds that, it is interpreted as 0. 3913 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 3914 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 3915 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 3916 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 3917 non_canon_x = 1; 3918 else 3919 non_canon_x = 0; 3920 3921 // CONVERT Y 3922 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 3923 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 3924 sig_y.w[0] = y.w[0]; 3925 3926 // CHECK IF Y IS CANONICAL 3927 // 9999999999999999999999999999999999(decimal) = 3928 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 3929 // [0, 10^34) is the 754r supported canonical range. 3930 // If the value exceeds that, it is interpreted as 0. 3931 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 3932 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 3933 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 3934 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 3935 non_canon_y = 1; 3936 else 3937 non_canon_y = 0; 3938 3939 // ZERO (CASE4) 3940 // some properties: 3941 // (+ZERO == -ZERO) => therefore ignore the sign 3942 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 3943 // ignore the exponent field 3944 // (Any non-canonical # is considered 0) 3945 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 3946 x_is_zero = 1; 3947 } 3948 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 3949 y_is_zero = 1; 3950 } 3951 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 3952 if (x_is_zero && y_is_zero) { 3953 res = 1; 3954 BID_RETURN (res); 3955 } 3956 // is x is zero, it is greater if Y is negative 3957 else if (x_is_zero) { 3958 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3959 BID_RETURN (res); 3960 } 3961 // is y is zero, X is greater if it is positive 3962 else if (y_is_zero) { 3963 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3964 BID_RETURN (res); 3965 } 3966 // OPPOSITE SIGN (CASE5) 3967 // now, if the sign bits differ, x is greater if y is negative 3968 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 3969 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 3970 BID_RETURN (res); 3971 } 3972 // REDUNDANT REPRESENTATIONS (CASE6) 3973 // if exponents are the same, then we have a simple comparison 3974 // of the significands 3975 if (exp_y == exp_x) { 3976 res = (((sig_x.w[1] > sig_y.w[1]) 3977 || (sig_x.w[1] == sig_y.w[1] 3978 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) != 3979 MASK_SIGN)); 3980 BID_RETURN (res); 3981 } 3982 // if both components are either bigger or smaller, 3983 // it is clear what needs to be done 3984 if ((sig_x.w[1] > sig_y.w[1] 3985 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 3986 && exp_x >= exp_y) { 3987 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3988 BID_RETURN (res); 3989 } 3990 if ((sig_x.w[1] < sig_y.w[1] 3991 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 3992 && exp_x <= exp_y) { 3993 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3994 BID_RETURN (res); 3995 } 3996 3997 diff = exp_x - exp_y; 3998 3999 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 4000 if (diff > 0) { // to simplify the loop below, 4001 4002 // if exp_x is 33 greater than exp_y, no need for compensation 4003 if (diff > 33) { 4004 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 4005 BID_RETURN (res); 4006 } // difference cannot be greater than 10^33 4007 4008 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 4009 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 4010 4011 4012 // if postitive, return whichever significand is larger 4013 // (converse if negative) 4014 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 4015 && sig_n_prime256.w[1] == sig_y.w[1] 4016 && (sig_n_prime256.w[0] == sig_y.w[0])) { 4017 res = 1; 4018 BID_RETURN (res); 4019 } // if equal, return 0 4020 { 4021 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 4022 || (sig_n_prime256.w[1] > sig_y.w[1]) 4023 || (sig_n_prime256.w[1] == sig_y.w[1] 4024 && sig_n_prime256.w[0] > 4025 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 4026 BID_RETURN (res); 4027 } 4028 } 4029 //else { //128 by 64 bit multiply -> 192 bits 4030 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 4031 4032 // if postitive, return whichever significand is larger 4033 // (converse if negative) 4034 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 4035 && (sig_n_prime192.w[0] == sig_y.w[0])) { 4036 res = 1; 4037 BID_RETURN (res); 4038 } // if equal, return 0 4039 { 4040 res = (((sig_n_prime192.w[2] > 0) 4041 || (sig_n_prime192.w[1] > sig_y.w[1]) 4042 || (sig_n_prime192.w[1] == sig_y.w[1] 4043 && sig_n_prime192.w[0] > 4044 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN)); 4045 BID_RETURN (res); 4046 } 4047 } 4048 4049 diff = exp_y - exp_x; 4050 4051 // if exp_x is 33 less than exp_y, no need for compensation 4052 if (diff > 33) { 4053 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 4054 BID_RETURN (res); 4055 } 4056 4057 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 4058 // adjust the y significand upwards 4059 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 4060 4061 // if postitive, return whichever significand is larger 4062 // (converse if negative) 4063 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 4064 && sig_n_prime256.w[1] == sig_x.w[1] 4065 && (sig_n_prime256.w[0] == sig_x.w[0])) { 4066 res = 1; 4067 BID_RETURN (res); 4068 } // if equal, return 0 4069 { 4070 res = 4071 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 4072 || (sig_n_prime256.w[1] > sig_x.w[1] 4073 || (sig_n_prime256.w[1] == sig_x.w[1] 4074 && sig_n_prime256.w[0] > 4075 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 4076 BID_RETURN (res); 4077 } 4078 } 4079 //else { //128 by 64 bit multiply -> 192 bits 4080 // adjust the y significand upwards 4081 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 4082 4083 // if postitive, return whichever significand is larger 4084 // (converse if negative) 4085 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 4086 && (sig_n_prime192.w[0] == sig_x.w[0])) { 4087 res = 1; 4088 BID_RETURN (res); 4089 } // if equal, return 0 4090 { 4091 res = (sig_n_prime192.w[2] != 0 4092 || (sig_n_prime192.w[1] > sig_x.w[1] 4093 || (sig_n_prime192.w[1] == sig_x.w[1] 4094 && sig_n_prime192.w[0] > 4095 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 4096 BID_RETURN (res); 4097 } 4098 } 4099 4100 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, 4101 bid128_signaling_not_less, x, 4102 y) 4103 4104 int res; 4105 int exp_x, exp_y; 4106 int diff; 4107 UINT128 sig_x, sig_y; 4108 UINT192 sig_n_prime192; 4109 UINT256 sig_n_prime256; 4110 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y; 4111 4112 // NaN (CASE1) 4113 // if either number is NAN, the comparison is unordered, 4114 // rather than equal : return 1 4115 if (((x.w[1] & MASK_NAN) == MASK_NAN) 4116 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 4117 *pfpsf |= INVALID_EXCEPTION; 4118 { 4119 res = 1; 4120 BID_RETURN (res); 4121 } 4122 } 4123 // SIMPLE (CASE2) 4124 // if all the bits are the same, these numbers are equal (not Greater). 4125 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 4126 res = 1; 4127 BID_RETURN (res); 4128 } 4129 // INFINITY (CASE3) 4130 if ((x.w[1] & MASK_INF) == MASK_INF) { 4131 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) } 4132 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) 4133 // x is -inf, so it is less than y unless y is -inf 4134 { 4135 res = (((y.w[1] & MASK_INF) == MASK_INF) 4136 && (y.w[1] & MASK_SIGN) == MASK_SIGN); 4137 BID_RETURN (res); 4138 } else 4139 // x is pos_inf, no way for it to be less than y 4140 { 4141 res = 1; 4142 BID_RETURN (res); 4143 } 4144 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 4145 // x is finite, so if y is positive infinity, then x is less, return 0 4146 // if y is negative infinity, then x is greater, return 1 4147 { 4148 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 4149 BID_RETURN (res); 4150 } 4151 } 4152 // CONVERT X 4153 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 4154 sig_x.w[0] = x.w[0]; 4155 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 4156 4157 // CHECK IF X IS CANONICAL 4158 // 9999999999999999999999999999999999(decimal) = 4159 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 4160 // [0, 10^34) is the 754r supported canonical range. 4161 // If the value exceeds that, it is interpreted as 0. 4162 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 4163 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 4164 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 4165 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 4166 non_canon_x = 1; 4167 else 4168 non_canon_x = 0; 4169 4170 // CONVERT Y 4171 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 4172 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 4173 sig_y.w[0] = y.w[0]; 4174 4175 // CHECK IF Y IS CANONICAL 4176 // 9999999999999999999999999999999999(decimal) = 4177 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 4178 // [0, 10^34) is the 754r supported canonical range. 4179 // If the value exceeds that, it is interpreted as 0. 4180 if ((sig_y.w[1] > 0x0001ed09bead87c0ull) 4181 || ((sig_y.w[1] == 0x0001ed09bead87c0ull) 4182 && (sig_y.w[0] > 0x378d8e63ffffffffull)) 4183 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) 4184 non_canon_y = 1; 4185 else 4186 non_canon_y = 0; 4187 4188 // ZERO (CASE4) 4189 // some properties: 4190 // (+ZERO == -ZERO) => therefore ignore the sign 4191 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore 4192 // ignore the exponent field 4193 // (Any non-canonical # is considered 0) 4194 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 4195 x_is_zero = 1; 4196 } 4197 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 4198 y_is_zero = 1; 4199 } 4200 // if both numbers are zero, neither is greater => return NOTGREATERTHAN 4201 if (x_is_zero && y_is_zero) { 4202 res = 1; 4203 BID_RETURN (res); 4204 } 4205 // is x is zero, it is greater if Y is negative 4206 else if (x_is_zero) { 4207 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 4208 BID_RETURN (res); 4209 } 4210 // is y is zero, X is greater if it is positive 4211 else if (y_is_zero) { 4212 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 4213 BID_RETURN (res); 4214 } 4215 // OPPOSITE SIGN (CASE5) 4216 // now, if the sign bits differ, x is greater if y is negative 4217 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) { 4218 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN); 4219 BID_RETURN (res); 4220 } 4221 // REDUNDANT REPRESENTATIONS (CASE6) 4222 4223 // if exponents are the same, then we have a simple comparison 4224 // of the significands 4225 if (exp_y == exp_x) { 4226 res = (((sig_x.w[1] > sig_y.w[1]) 4227 || (sig_x.w[1] == sig_y.w[1] 4228 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) == 4229 MASK_SIGN)); 4230 BID_RETURN (res); 4231 } 4232 // if both components are either bigger or smaller, 4233 // it is clear what needs to be done 4234 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0] 4235 && exp_x > exp_y) { 4236 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 4237 BID_RETURN (res); 4238 } 4239 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0] 4240 && exp_x < exp_y) { 4241 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 4242 BID_RETURN (res); 4243 } 4244 4245 diff = exp_x - exp_y; 4246 4247 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 4248 if (diff > 0) { // to simplify the loop below, 4249 4250 // if exp_x is 33 greater than exp_y, no need for compensation 4251 if (diff > 33) { 4252 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 4253 BID_RETURN (res); 4254 } // difference cannot be greater than 10^33 4255 4256 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 4257 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]); 4258 4259 4260 // if postitive, return whichever significand is larger 4261 // (converse if negative) 4262 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 4263 && sig_n_prime256.w[1] == sig_y.w[1] 4264 && (sig_n_prime256.w[0] == sig_y.w[0])) { 4265 res = 1; 4266 BID_RETURN (res); 4267 } // if equal, return 1 4268 { 4269 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0) 4270 || (sig_n_prime256.w[1] > sig_y.w[1]) 4271 || (sig_n_prime256.w[1] == sig_y.w[1] 4272 && sig_n_prime256.w[0] > 4273 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 4274 BID_RETURN (res); 4275 } 4276 } 4277 //else { //128 by 64 bit multiply -> 192 bits 4278 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x); 4279 4280 // if postitive, return whichever significand is larger 4281 // (converse if negative) 4282 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 4283 && (sig_n_prime192.w[0] == sig_y.w[0])) { 4284 res = 1; 4285 BID_RETURN (res); 4286 } // if equal, return 1 4287 { 4288 res = (((sig_n_prime192.w[2] > 0) 4289 || (sig_n_prime192.w[1] > sig_y.w[1]) 4290 || (sig_n_prime192.w[1] == sig_y.w[1] 4291 && sig_n_prime192.w[0] > 4292 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)); 4293 BID_RETURN (res); 4294 } 4295 } 4296 4297 diff = exp_y - exp_x; 4298 4299 // if exp_x is 33 less than exp_y, no need for compensation 4300 if (diff > 33) { 4301 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 4302 BID_RETURN (res); 4303 } 4304 4305 if (diff > 19) { //128 by 128 bit multiply -> 256 bits 4306 // adjust the y significand upwards 4307 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]); 4308 4309 4310 // if postitive, return whichever significand is larger 4311 // (converse if negative) 4312 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0) 4313 && sig_n_prime256.w[1] == sig_x.w[1] 4314 && (sig_n_prime256.w[0] == sig_x.w[0])) { 4315 res = 1; 4316 BID_RETURN (res); 4317 } // if equal, return 1 4318 { 4319 res = 4320 ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0 4321 && (sig_n_prime256.w[1] < sig_x.w[1] 4322 || (sig_n_prime256.w[1] == sig_x.w[1] 4323 && sig_n_prime256.w[0] < 4324 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 4325 BID_RETURN (res); 4326 } 4327 } 4328 //else { //128 by 64 bit multiply -> 192 bits 4329 // adjust the y significand upwards 4330 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y); 4331 4332 // if postitive, return whichever significand is larger (converse if negative) 4333 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1] 4334 && (sig_n_prime192.w[0] == sig_x.w[0])) { 4335 res = 1; 4336 BID_RETURN (res); 4337 } // if equal, return 1 4338 { 4339 res = (sig_n_prime192.w[2] == 0 4340 && (sig_n_prime192.w[1] < sig_x.w[1] 4341 || (sig_n_prime192.w[1] == sig_x.w[1] 4342 && sig_n_prime192.w[0] < 4343 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN); 4344 BID_RETURN (res); 4345 } 4346 } 4347