bid128_compare.c revision 1.1.1.2
1/* Copyright (C) 2007-2013 Free Software Foundation, Inc. 2 3This file is part of GCC. 4 5GCC is free software; you can redistribute it and/or modify it under 6the terms of the GNU General Public License as published by the Free 7Software Foundation; either version 3, or (at your option) any later 8version. 9 10GCC is distributed in the hope that it will be useful, but WITHOUT ANY 11WARRANTY; without even the implied warranty of MERCHANTABILITY or 12FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13for more details. 14 15Under Section 7 of GPL version 3, you are granted additional 16permissions described in the GCC Runtime Library Exception, version 173.1, as published by the Free Software Foundation. 18 19You should have received a copy of the GNU General Public License and 20a copy of the GCC Runtime Library Exception along with this program; 21see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 22<http://www.gnu.org/licenses/>. */ 23 24#include "bid_internal.h" 25 26BID128_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 38if (((x.w[1] & MASK_NAN) == MASK_NAN) 39 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 40if ((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. 51if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 52 res = 1; 53 BID_RETURN (res); 54} 55 // INFINITY (CASE3) 56if ((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} 65if ((y.w[1] & MASK_INF) == MASK_INF) { 66 res = 0; 67 BID_RETURN (res); 68} 69 // CONVERT X 70sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 71sig_x.w[0] = x.w[0]; 72exp_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. 79if ((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; 84else 85 non_canon_x = 0; 86 87 // CONVERT Y 88exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 89sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 90sig_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. 97if ((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; 102else 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) 110if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 111 x_is_zero = 1; 112} 113if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 114 y_is_zero = 1; 115} 116 117if (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 126if ((x.w[1] ^ y.w[1]) & MASK_SIGN) { 127 res = 0; 128 BID_RETURN (res); 129} 130 // REDUNDANT REPRESENTATIONS (CASE6) 131if (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 138if (exp_y - exp_x > 33) { 139 res = 0; 140 BID_RETURN (res); 141} // difference cannot be greater than 10^33 142 143if (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 166BID128_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 180if (((x.w[1] & MASK_NAN) == MASK_NAN) 181 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 182if ((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). 193if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 194 res = 0; 195 BID_RETURN (res); 196} 197 // INFINITY (CASE3) 198if ((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 220sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 221sig_x.w[0] = x.w[0]; 222exp_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. 229if ((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; 234else 235 non_canon_x = 0; 236 237 // CONVERT Y 238exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 239sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 240sig_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. 247if ((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; 252else 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) 261if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 262 x_is_zero = 1; 263} 264if (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 268if (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 273else 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 278else 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 284if (((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 291if (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 300if ((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} 308if ((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 317diff = exp_x - exp_y; 318 319 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 320if (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 368diff = exp_y - exp_x; 369 370 // if exp_x is 33 less than exp_y, no need for compensation 371if (diff > 33) { 372 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 373 BID_RETURN (res); 374} 375 376if (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) 403if ((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 418BID128_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 433if (((x.w[1] & MASK_NAN) == MASK_NAN) 434 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 435if ((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). 446if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 447 res = 1; 448 BID_RETURN (res); 449} 450 // INFINITY (CASE3) 451if ((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 474sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 475sig_x.w[0] = x.w[0]; 476exp_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. 483if ((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; 488else 489 non_canon_x = 0; 490 491 // CONVERT Y 492exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 493sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 494sig_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. 501if ((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; 506else 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) 515if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 516 x_is_zero = 1; 517} 518if (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 522if (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 527else 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 532else 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 538if (((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 545if (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 554if (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} 559if (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 565diff = exp_x - exp_y; 566 567 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 568if (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 617diff = exp_y - exp_x; 618 619 // if exp_x is 33 less than exp_y, no need for compensation 620if (diff > 33) { 621 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 622 BID_RETURN (res); 623} 624 625if (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) 654if ((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 669BID128_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 685if (((x.w[1] & MASK_NAN) == MASK_NAN) 686 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 687if ((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). 698if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 699 res = 0; 700 BID_RETURN (res); 701} 702 // INFINITY (CASE3) 703if ((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 725sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 726sig_x.w[0] = x.w[0]; 727exp_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. 734if ((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; 739else 740 non_canon_x = 0; 741 742 // CONVERT Y 743exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 744sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 745sig_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. 752if ((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; 757else 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) 766if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 767 x_is_zero = 1; 768} 769if (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 773if (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 778else 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 783else 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 789if (((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 796if (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 805if (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} 810if (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 816diff = exp_x - exp_y; 817 818 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 819if (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 868diff = exp_y - exp_x; 869 870 // if exp_x is 33 less than exp_y, no need for compensation 871if (diff > 33) { 872 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 873 BID_RETURN (res); 874} 875 876if (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) 905if ((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 920BID128_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 933if (((x.w[1] & MASK_NAN) == MASK_NAN) 934 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 935if ((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. 946if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 947 res = 0; 948 BID_RETURN (res); 949} 950 // INFINITY (CASE3) 951if ((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 974sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 975sig_x.w[0] = x.w[0]; 976exp_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. 983if ((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; 988else 989 non_canon_x = 0; 990 991 // CONVERT Y 992exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 993sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 994sig_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. 1001if ((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; 1006else 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) 1015if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1016 x_is_zero = 1; 1017} 1018if (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 1022if (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 1027else 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 1032else 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 1038if (((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 1045if (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 1054if ((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} 1060if ((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 1067diff = exp_x - exp_y; 1068 1069 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 1070if (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 1119diff = exp_y - exp_x; 1120 1121 // if exp_x is 33 less than exp_y, no need for compensation 1122if (diff > 33) { 1123 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1124 BID_RETURN (res); 1125} 1126 1127if (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) 1155if ((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 1170BID128_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 1184if (((x.w[1] & MASK_NAN) == MASK_NAN) 1185 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 1186if ((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). 1197if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 1198 res = 1; 1199 BID_RETURN (res); 1200} 1201 // INFINITY (CASE3) 1202if ((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 1224sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 1225sig_x.w[0] = x.w[0]; 1226exp_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. 1233if ((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; 1238else 1239 non_canon_x = 0; 1240 1241 // CONVERT Y 1242exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 1243sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 1244sig_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. 1251if ((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; 1256else 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) 1265if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1266 x_is_zero = 1; 1267} 1268if (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 1272if (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 1277else 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 1282else 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 1288if (((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 1295if (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 1306if ((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} 1312if ((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 1319diff = exp_x - exp_y; 1320 1321 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 1322if (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 1371diff = exp_y - exp_x; 1372 1373 // if exp_x is 33 less than exp_y, no need for compensation 1374if (diff > 33) { 1375 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1376 BID_RETURN (res); 1377} 1378 1379if (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) 1408if ((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 1423BID128_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 1437if (((x.w[1] & MASK_NAN) == MASK_NAN) 1438 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 1439if ((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. 1450if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 1451 res = 0; 1452 BID_RETURN (res); 1453} 1454 // INFINITY (CASE3) 1455if ((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 1478sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 1479sig_x.w[0] = x.w[0]; 1480exp_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. 1487if ((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; 1492else 1493 non_canon_x = 0; 1494 1495 // CONVERT Y 1496exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 1497sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 1498sig_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. 1505if ((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; 1510else 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) 1519if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1520 x_is_zero = 1; 1521} 1522if (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 1526if (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 1531else 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 1536else 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 1542if (((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 1549if (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 1558if ((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} 1564if ((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 1571diff = exp_x - exp_y; 1572 1573 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 1574if (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 1623diff = exp_y - exp_x; 1624 1625 // if exp_x is 33 less than exp_y, no need for compensation 1626if (diff > 33) { 1627 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 1628 BID_RETURN (res); 1629} 1630 1631if (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) 1660if ((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 1675BID128_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 1688if (((x.w[1] & MASK_NAN) == MASK_NAN) 1689 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 1690if ((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. 1701if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 1702 res = 0; 1703 BID_RETURN (res); 1704} 1705 // INFINITY (CASE3) 1706if ((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} 1715if ((y.w[1] & MASK_INF) == MASK_INF) { 1716 res = 1; 1717 BID_RETURN (res); 1718} 1719 // CONVERT X 1720sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 1721sig_x.w[0] = x.w[0]; 1722exp_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. 1729if ((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; 1734else 1735 non_canon_x = 0; 1736 1737 // CONVERT Y 1738exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 1739sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 1740sig_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. 1747if ((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; 1752else 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) 1760if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1761 x_is_zero = 1; 1762} 1763if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 1764 y_is_zero = 1; 1765} 1766 1767if (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 1776if ((x.w[1] ^ y.w[1]) & MASK_SIGN) { 1777 res = 1; 1778 BID_RETURN (res); 1779} 1780 // REDUNDANT REPRESENTATIONS (CASE6) 1781if (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 1788if (exp_y - exp_x > 33) { 1789 res = 1; 1790 BID_RETURN (res); 1791} // difference cannot be greater than 10^33 1792 1793if (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 1816BID128_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 1830if (((x.w[1] & MASK_NAN) == MASK_NAN) 1831 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 1832if ((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). 1843if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 1844 res = 1; 1845 BID_RETURN (res); 1846} 1847 // INFINITY (CASE3) 1848if ((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 1869sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 1870sig_x.w[0] = x.w[0]; 1871exp_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. 1878if ((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; 1883else 1884 non_canon_x = 0; 1885 1886 // CONVERT Y 1887exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 1888sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 1889sig_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. 1896if ((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; 1901else 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) 1910if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1911 x_is_zero = 1; 1912} 1913if (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 1917if (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 1922else 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 1927else 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 1933if (((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 1940if (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 1949if ((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} 1955if ((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 1962diff = exp_x - exp_y; 1963 1964 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 1965if (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 2014diff = exp_y - exp_x; 2015 2016 // if exp_x is 33 less than exp_y, no need for compensation 2017if (diff > 33) { 2018 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 2019 BID_RETURN (res); 2020} 2021 2022if (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) 2051if ((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 2066BID128_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 2080if (((x.w[1] & MASK_NAN) == MASK_NAN) 2081 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 2082if ((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). 2093if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 2094 res = 1; 2095 BID_RETURN (res); 2096} 2097 // INFINITY (CASE3) 2098if ((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 2121sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 2122sig_x.w[0] = x.w[0]; 2123exp_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. 2130if ((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; 2135else 2136 non_canon_x = 0; 2137 2138 // CONVERT Y 2139exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 2140sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 2141sig_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. 2148if ((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; 2153else 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) 2162if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 2163 x_is_zero = 1; 2164} 2165if (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 2169if (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 2174else 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 2179else 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 2185if (((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 2193if (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 2202if (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} 2207if (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 2213diff = exp_x - exp_y; 2214 2215 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 2216if (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 2265diff = exp_y - exp_x; 2266 2267 // if exp_x is 33 less than exp_y, no need for compensation 2268if (diff > 33) { 2269 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 2270 BID_RETURN (res); 2271} 2272 2273if (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) 2302if ((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 2317BID128_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 2324if (((x.w[1] & MASK_NAN) == MASK_NAN) 2325 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 2326if ((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 2341BID128_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 2348if (((x.w[1] & MASK_NAN) == MASK_NAN) 2349 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 2350if ((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 2365BID128_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 2379if (((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). 2389if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 2390 res = 0; 2391 BID_RETURN (res); 2392} 2393 // INFINITY (CASE3) 2394if ((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 2415sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 2416sig_x.w[0] = x.w[0]; 2417exp_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. 2424if ((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; 2429else 2430 non_canon_x = 0; 2431 2432 // CONVERT Y 2433exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 2434sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 2435sig_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. 2442if ((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; 2447else 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) 2456if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 2457 x_is_zero = 1; 2458} 2459if (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 2463if (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 2468else 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 2473else 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 2479if (((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 2486if (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 2495if ((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} 2503if ((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 2512diff = exp_x - exp_y; 2513 2514 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 2515if (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 2563diff = exp_y - exp_x; 2564 2565 // if exp_x is 33 less than exp_y, no need for compensation 2566if (diff > 33) { 2567 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 2568 BID_RETURN (res); 2569} 2570 2571if (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) 2599if ((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 2614BID128_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 2629if (((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). 2639if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 2640 res = 1; 2641 BID_RETURN (res); 2642} 2643 // INFINITY (CASE3) 2644if ((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 2667sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 2668sig_x.w[0] = x.w[0]; 2669exp_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. 2676if ((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; 2681else 2682 non_canon_x = 0; 2683 2684 // CONVERT Y 2685exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 2686sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 2687sig_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. 2694if ((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; 2699else 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) 2708if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 2709 x_is_zero = 1; 2710} 2711if (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 2715if (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 2720else 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 2725else 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 2731if (((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 2738if (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 2747if (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} 2752if (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 2758diff = exp_x - exp_y; 2759 2760 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 2761if (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 2810diff = exp_y - exp_x; 2811 2812 // if exp_x is 33 less than exp_y, no need for compensation 2813if (diff > 33) { 2814 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 2815 BID_RETURN (res); 2816} 2817 2818if (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) 2847if ((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 2862BID128_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 2877if (((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). 2887if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 2888 res = 0; 2889 BID_RETURN (res); 2890} 2891 // INFINITY (CASE3) 2892if ((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 2913sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 2914sig_x.w[0] = x.w[0]; 2915exp_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. 2922if ((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; 2927else 2928 non_canon_x = 0; 2929 2930 // CONVERT Y 2931exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 2932sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 2933sig_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. 2940if ((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; 2945else 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) 2954if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 2955 x_is_zero = 1; 2956} 2957if (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 2961if (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 2966else 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 2971else 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 2977if (((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 2984if (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 2993if (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} 2998if (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 3004diff = exp_x - exp_y; 3005 3006 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 3007if (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 3056diff = exp_y - exp_x; 3057 3058 // if exp_x is 33 less than exp_y, no need for compensation 3059if (diff > 33) { 3060 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 3061 BID_RETURN (res); 3062} 3063 3064if (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) 3093if ((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 3108BID128_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 3122if (((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. 3132if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 3133 res = 0; 3134 BID_RETURN (res); 3135} 3136 // INFINITY (CASE3) 3137if ((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 3160sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 3161sig_x.w[0] = x.w[0]; 3162exp_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. 3169if ((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; 3174else 3175 non_canon_x = 0; 3176 3177 // CONVERT Y 3178exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 3179sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 3180sig_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. 3187if ((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; 3192else 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) 3201if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 3202 x_is_zero = 1; 3203} 3204if (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 3208if (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 3213else 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 3218else 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 3224if (((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 3231if (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 3240if ((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} 3246if ((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 3253diff = exp_x - exp_y; 3254 3255 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 3256if (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 3305diff = exp_y - exp_x; 3306 3307 // if exp_x is 33 less than exp_y, |x| < |y|, return 1 if positive 3308if (diff > 33) { 3309 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3310 BID_RETURN (res); 3311} 3312 3313if (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) 3342if ((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 3357BID128_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 3372if (((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). 3382if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 3383 res = 1; 3384 BID_RETURN (res); 3385} 3386 // INFINITY (CASE3) 3387if ((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 3408sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 3409sig_x.w[0] = x.w[0]; 3410exp_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. 3417if ((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; 3422else 3423 non_canon_x = 0; 3424 3425 // CONVERT Y 3426exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 3427sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 3428sig_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. 3435if ((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; 3440else 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) 3449if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 3450 x_is_zero = 1; 3451} 3452if (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 3456if (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 3461else 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 3466else 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 3472if (((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 3479if (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 3488if ((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} 3494if ((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 3501diff = exp_x - exp_y; 3502 3503 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 3504if (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 3553diff = exp_y - exp_x; 3554 3555 // if exp_x is 33 less than exp_y, no need for compensation 3556if (diff > 33) { 3557 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3558 BID_RETURN (res); 3559} 3560 3561if (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) 3590if ((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 3605BID128_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 3619if (((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. 3629if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 3630 res = 0; 3631 BID_RETURN (res); 3632} 3633 // INFINITY (CASE3) 3634if ((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 3657sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 3658sig_x.w[0] = x.w[0]; 3659exp_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. 3666if ((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; 3671else 3672 non_canon_x = 0; 3673 3674 // CONVERT Y 3675exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 3676sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 3677sig_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. 3684if ((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; 3689else 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) 3698if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 3699 x_is_zero = 1; 3700} 3701if (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 3705if (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 3710else 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 3715else 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 3721if (((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 3728if (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 3737if ((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} 3743if ((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 3750diff = exp_x - exp_y; 3751 3752 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 3753if (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 3802diff = exp_y - exp_x; 3803 3804 // if exp_x is 33 less than exp_y, no need for compensation 3805if (diff > 33) { 3806 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 3807 BID_RETURN (res); 3808} 3809 3810if (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) 3838if ((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 3853BID128_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 3868if (((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). 3878if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 3879 res = 1; 3880 BID_RETURN (res); 3881} 3882 // INFINITY (CASE3) 3883if ((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 3904sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 3905sig_x.w[0] = x.w[0]; 3906exp_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. 3913if ((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; 3918else 3919 non_canon_x = 0; 3920 3921 // CONVERT Y 3922exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 3923sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 3924sig_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. 3931if ((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; 3936else 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) 3945if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 3946 x_is_zero = 1; 3947} 3948if (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 3952if (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 3957else 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 3962else 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 3968if (((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 3975if (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 3984if ((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} 3990if ((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 3997diff = exp_x - exp_y; 3998 3999 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 4000if (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 4049diff = exp_y - exp_x; 4050 4051 // if exp_x is 33 less than exp_y, no need for compensation 4052if (diff > 33) { 4053 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 4054 BID_RETURN (res); 4055} 4056 4057if (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) 4085if ((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 4100BID128_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 4115if (((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). 4125if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) { 4126 res = 1; 4127 BID_RETURN (res); 4128} 4129 // INFINITY (CASE3) 4130if ((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 4153sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 4154sig_x.w[0] = x.w[0]; 4155exp_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. 4162if ((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; 4167else 4168 non_canon_x = 0; 4169 4170 // CONVERT Y 4171exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 4172sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 4173sig_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. 4180if ((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; 4185else 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) 4194if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 4195 x_is_zero = 1; 4196} 4197if (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 4201if (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 4206else 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 4211else 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 4217if (((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 4225if (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 4234if (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} 4239if (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 4245diff = exp_x - exp_y; 4246 4247 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 4248if (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 4297diff = exp_y - exp_x; 4298 4299 // if exp_x is 33 less than exp_y, no need for compensation 4300if (diff > 33) { 4301 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 4302 BID_RETURN (res); 4303} 4304 4305if (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) 4333if ((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