* gcc-interface/decl.c (gnat_to_gnu_field): Do not set the alignment
[official-gcc.git] / libgcc / config / libbid / bid128_compare.c
blobb14a40f2a2d7c09b8a18644e8afbd88ed71353fb
1 /* Copyright (C) 2007-2017 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
24 #include "bid_internal.h"
26 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_equal, x, y)
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;
35 // NaN (CASE1)
36 // if either number is NAN, the comparison is unordered,
37 // rather than equal : return 0
38 if (((x.w[1] & MASK_NAN) == MASK_NAN)
39 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
40 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
41 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
42 *pfpsf |= INVALID_EXCEPTION;
45 res = 0;
46 BID_RETURN (res);
49 // SIMPLE (CASE2)
50 // if all the bits are the same, these numbers are equivalent.
51 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
52 res = 1;
53 BID_RETURN (res);
55 // INFINITY (CASE3)
56 if ((x.w[1] & MASK_INF) == MASK_INF) {
57 if ((y.w[1] & MASK_INF) == MASK_INF) {
58 res = (((x.w[1] ^ y.w[1]) & MASK_SIGN) != MASK_SIGN);
59 BID_RETURN (res);
60 } else {
61 res = 0;
62 BID_RETURN (res);
65 if ((y.w[1] & MASK_INF) == MASK_INF) {
66 res = 0;
67 BID_RETURN (res);
69 // CONVERT X
70 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
71 sig_x.w[0] = x.w[0];
72 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
74 // CHECK IF X IS CANONICAL
75 // 9999999999999999999999999999999999(decimal) =
76 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
77 // [0, 10^34) is the 754r supported canonical range.
78 // If the value exceeds that, it is interpreted as 0.
79 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
80 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
81 && (sig_x.w[0] > 0x378d8e63ffffffffull))
82 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
83 non_canon_x = 1;
84 else
85 non_canon_x = 0;
87 // CONVERT Y
88 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
89 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
90 sig_y.w[0] = y.w[0];
92 // CHECK IF Y IS CANONICAL
93 // 9999999999999999999999999999999999(decimal) =
94 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
95 // [0, 10^34) is the 754r supported canonical range.
96 // If the value exceeds that, it is interpreted as 0.
97 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
98 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
99 && (sig_y.w[0] > 0x378d8e63ffffffffull))
100 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
101 non_canon_y = 1;
102 else
103 non_canon_y = 0;
105 // some properties:
106 // (+ZERO == -ZERO) => therefore ignore the sign
107 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
108 // ignore the exponent field
109 // (Any non-canonical # is considered 0)
110 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
111 x_is_zero = 1;
113 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
114 y_is_zero = 1;
117 if (x_is_zero && y_is_zero) {
118 res = 1;
119 BID_RETURN (res);
120 } else if ((x_is_zero && !y_is_zero) || (!x_is_zero && y_is_zero)) {
121 res = 0;
122 BID_RETURN (res);
124 // OPPOSITE SIGN (CASE5)
125 // now, if the sign bits differ => not equal : return 0
126 if ((x.w[1] ^ y.w[1]) & MASK_SIGN) {
127 res = 0;
128 BID_RETURN (res);
130 // REDUNDANT REPRESENTATIONS (CASE6)
131 if (exp_x > exp_y) { // to simplify the loop below,
132 SWAP (exp_x, exp_y, exp_t); // put the larger exp in y,
133 SWAP (sig_x.w[1], sig_y.w[1], sig_t.w[1]); // and the smaller exp in x
134 SWAP (sig_x.w[0], sig_y.w[0], sig_t.w[0]); // and the smaller exp in x
138 if (exp_y - exp_x > 33) {
139 res = 0;
140 BID_RETURN (res);
141 } // difference cannot be greater than 10^33
143 if (exp_y - exp_x > 19) {
144 // recalculate y's significand upwards
145 __mul_128x128_to_256 (sig_n_prime256, sig_y,
146 ten2k128[exp_y - exp_x - 20]);
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);
155 //else{
156 // recalculate y's significand upwards
157 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y);
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);
166 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_greater, x,
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;
177 // NaN (CASE1)
178 // if either number is NAN, the comparison is unordered, rather than
179 // equal : return 0
180 if (((x.w[1] & MASK_NAN) == MASK_NAN)
181 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
182 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
183 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
184 *pfpsf |= INVALID_EXCEPTION;
187 res = 0;
188 BID_RETURN (res);
191 // SIMPLE (CASE2)
192 // if all the bits are the same, these numbers are equal (not Greater).
193 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
194 res = 0;
195 BID_RETURN (res);
197 // INFINITY (CASE3)
198 if ((x.w[1] & MASK_INF) == MASK_INF) {
199 // if x is neg infinity, there is no way it is greater than y, return 0
200 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
201 res = 0;
202 BID_RETURN (res);
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);
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
215 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
216 BID_RETURN (res);
219 // CONVERT X
220 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
221 sig_x.w[0] = x.w[0];
222 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
224 // CHECK IF X IS CANONICAL
225 // 9999999999999999999999999999999999(decimal) =
226 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
227 // [0, 10^34) is the 754r supported canonical range.
228 // If the value exceeds that, it is interpreted as 0.
229 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
230 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
231 && (sig_x.w[0] > 0x378d8e63ffffffffull))
232 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
233 non_canon_x = 1;
234 else
235 non_canon_x = 0;
237 // CONVERT Y
238 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
239 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
240 sig_y.w[0] = y.w[0];
242 // CHECK IF Y IS CANONICAL
243 // 9999999999999999999999999999999999(decimal) =
244 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
245 // [0, 10^34) is the 754r supported canonical range.
246 // If the value exceeds that, it is interpreted as 0.
247 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
248 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
249 && (sig_y.w[0] > 0x378d8e63ffffffffull))
250 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
251 non_canon_y = 1;
252 else
253 non_canon_y = 0;
255 // ZERO (CASE4)
256 // some properties:
257 // (+ZERO == -ZERO) => therefore ignore the sign
258 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
259 // ignore the exponent field
260 // (Any non-canonical # is considered 0)
261 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
262 x_is_zero = 1;
264 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
265 y_is_zero = 1;
267 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
268 if (x_is_zero && y_is_zero) {
269 res = 0;
270 BID_RETURN (res);
272 // is x is zero, it is greater if Y is negative
273 else if (x_is_zero) {
274 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
275 BID_RETURN (res);
277 // is y is zero, X is greater if it is positive
278 else if (y_is_zero) {
279 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
280 BID_RETURN (res);
282 // OPPOSITE SIGN (CASE5)
283 // now, if the sign bits differ, x is greater if y is negative
284 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
285 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
286 BID_RETURN (res);
288 // REDUNDANT REPRESENTATIONS (CASE6)
289 // if exponents are the same, then we have a simple comparison
290 // of the significands
291 if (exp_y == exp_x) {
292 res = (((sig_x.w[1] > sig_y.w[1])
293 || (sig_x.w[1] == sig_y.w[1]
294 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
295 MASK_SIGN));
296 BID_RETURN (res);
298 // if both components are either bigger or smaller,
299 // it is clear what needs to be done
300 if ((sig_x.w[1] > sig_y.w[1]
301 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
302 && exp_x >= exp_y) {
304 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
305 BID_RETURN (res);
308 if ((sig_x.w[1] < sig_y.w[1]
309 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
310 && exp_x <= exp_y) {
312 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
313 BID_RETURN (res);
317 diff = exp_x - exp_y;
319 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
320 if (diff > 0) { // to simplify the loop below,
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
328 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
329 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
348 //else { //128 by 64 bit multiply -> 192 bits
349 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
368 diff = exp_y - exp_x;
370 // if exp_x is 33 less than exp_y, no need for compensation
371 if (diff > 33) {
372 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
373 BID_RETURN (res);
376 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
377 // adjust the y significand upwards
378 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
401 // if postitive, return whichever significand is larger
402 // (converse if negative)
403 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
404 && (sig_n_prime192.w[0] == sig_x.w[0])) {
405 res = 0;
406 BID_RETURN (res);
407 } // if equal, return 0
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);
418 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
419 bid128_quiet_greater_equal, x,
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;
430 // NaN (CASE1)
431 // if either number is NAN, the comparison is unordered,
432 // rather than equal : return 1
433 if (((x.w[1] & MASK_NAN) == MASK_NAN)
434 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
435 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
436 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
437 *pfpsf |= INVALID_EXCEPTION;
440 res = 0;
441 BID_RETURN (res);
444 // SIMPLE (CASE2)
445 // if all the bits are the same, these numbers are equal (not Greater).
446 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
447 res = 1;
448 BID_RETURN (res);
450 // INFINITY (CASE3)
451 if ((x.w[1] & MASK_INF) == MASK_INF) {
452 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
453 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
454 // x is -inf, so it is less than y unless y is -inf
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
462 res = 1;
463 BID_RETURN (res);
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
469 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
470 BID_RETURN (res);
473 // CONVERT X
474 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
475 sig_x.w[0] = x.w[0];
476 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
478 // CHECK IF X IS CANONICAL
479 // 9999999999999999999999999999999999(decimal) =
480 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
481 // [0, 10^34) is the 754r supported canonical range.
482 // If the value exceeds that, it is interpreted as 0.
483 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
484 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
485 && (sig_x.w[0] > 0x378d8e63ffffffffull))
486 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
487 non_canon_x = 1;
488 else
489 non_canon_x = 0;
491 // CONVERT Y
492 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
493 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
494 sig_y.w[0] = y.w[0];
496 // CHECK IF Y IS CANONICAL
497 // 9999999999999999999999999999999999(decimal) =
498 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
499 // [0, 10^34) is the 754r supported canonical range.
500 // If the value exceeds that, it is interpreted as 0.
501 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
502 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
503 && (sig_y.w[0] > 0x378d8e63ffffffffull))
504 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
505 non_canon_y = 1;
506 else
507 non_canon_y = 0;
509 // ZERO (CASE4)
510 // some properties:
511 // (+ZERO == -ZERO) => therefore ignore the sign
512 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
513 // ignore the exponent field
514 // (Any non-canonical # is considered 0)
515 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
516 x_is_zero = 1;
518 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
519 y_is_zero = 1;
521 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
522 if (x_is_zero && y_is_zero) {
523 res = 1;
524 BID_RETURN (res);
526 // is x is zero, it is greater if Y is negative
527 else if (x_is_zero) {
528 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
529 BID_RETURN (res);
531 // is y is zero, X is greater if it is positive
532 else if (y_is_zero) {
533 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
534 BID_RETURN (res);
536 // OPPOSITE SIGN (CASE5)
537 // now, if the sign bits differ, x is greater if y is negative
538 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
539 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
540 BID_RETURN (res);
542 // REDUNDANT REPRESENTATIONS (CASE6)
543 // if exponents are the same, then we have a simple comparison of the
544 // significands
545 if (exp_y == exp_x) {
546 res = (((sig_x.w[1] > sig_y.w[1])
547 || (sig_x.w[1] == sig_y.w[1]
548 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
549 MASK_SIGN));
550 BID_RETURN (res);
552 // if both components are either bigger or smaller,
553 // it is clear what needs to be done
554 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
555 && exp_x > exp_y) {
556 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
557 BID_RETURN (res);
559 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
560 && exp_x < exp_y) {
561 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
562 BID_RETURN (res);
565 diff = exp_x - exp_y;
567 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
568 if (diff > 0) { // to simplify the loop below,
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
576 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
577 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
597 //else { //128 by 64 bit multiply -> 192 bits
598 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
617 diff = exp_y - exp_x;
619 // if exp_x is 33 less than exp_y, no need for compensation
620 if (diff > 33) {
621 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
622 BID_RETURN (res);
625 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
626 // adjust the y significand upwards
627 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
652 // if postitive, return whichever significand is larger
653 // (converse if negative)
654 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
655 && (sig_n_prime192.w[0] == sig_x.w[0])) {
656 res = 1;
657 BID_RETURN (res);
658 } // if equal, return 1
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);
669 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
670 bid128_quiet_greater_unordered,
671 x, y)
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;
681 // NaN (CASE1)
682 // if either number is NAN, the comparison is unordered,
683 // rather than
684 // equal : return 1
685 if (((x.w[1] & MASK_NAN) == MASK_NAN)
686 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
687 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
688 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
689 *pfpsf |= INVALID_EXCEPTION;
692 res = 1;
693 BID_RETURN (res);
696 // SIMPLE (CASE2)
697 // if all the bits are the same, these numbers are equal (not Greater).
698 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
699 res = 0;
700 BID_RETURN (res);
702 // INFINITY (CASE3)
703 if ((x.w[1] & MASK_INF) == MASK_INF) {
704 // if x is neg infinity, there is no way it is greater than y, return 0
705 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
706 res = 0;
707 BID_RETURN (res);
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);
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
720 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
721 BID_RETURN (res);
724 // CONVERT X
725 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
726 sig_x.w[0] = x.w[0];
727 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
729 // CHECK IF X IS CANONICAL
730 // 9999999999999999999999999999999999(decimal) =
731 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
732 // [0, 10^34) is the 754r supported canonical range.
733 // If the value exceeds that, it is interpreted as 0.
734 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
735 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
736 && (sig_x.w[0] > 0x378d8e63ffffffffull))
737 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
738 non_canon_x = 1;
739 else
740 non_canon_x = 0;
742 // CONVERT Y
743 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
744 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
745 sig_y.w[0] = y.w[0];
747 // CHECK IF Y IS CANONICAL
748 // 9999999999999999999999999999999999(decimal) =
749 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
750 // [0, 10^34) is the 754r supported canonical range.
751 // If the value exceeds that, it is interpreted as 0.
752 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
753 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
754 && (sig_y.w[0] > 0x378d8e63ffffffffull))
755 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
756 non_canon_y = 1;
757 else
758 non_canon_y = 0;
760 // ZERO (CASE4)
761 // some properties:
762 // (+ZERO == -ZERO) => therefore ignore the sign
763 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
764 // ignore the exponent field
765 // (Any non-canonical # is considered 0)
766 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
767 x_is_zero = 1;
769 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
770 y_is_zero = 1;
772 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
773 if (x_is_zero && y_is_zero) {
774 res = 0;
775 BID_RETURN (res);
777 // is x is zero, it is greater if Y is negative
778 else if (x_is_zero) {
779 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
780 BID_RETURN (res);
782 // is y is zero, X is greater if it is positive
783 else if (y_is_zero) {
784 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
785 BID_RETURN (res);
787 // OPPOSITE SIGN (CASE5)
788 // now, if the sign bits differ, x is greater if y is negative
789 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
790 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
791 BID_RETURN (res);
793 // REDUNDANT REPRESENTATIONS (CASE6)
794 // if exponents are the same, then we have a simple comparison of the
795 // significands
796 if (exp_y == exp_x) {
797 res = (((sig_x.w[1] > sig_y.w[1])
798 || (sig_x.w[1] == sig_y.w[1]
799 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
800 MASK_SIGN));
801 BID_RETURN (res);
803 // if both components are either bigger or smaller,
804 // it is clear what needs to be done
805 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
806 && exp_x > exp_y) {
807 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
808 BID_RETURN (res);
810 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
811 && exp_x < exp_y) {
812 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
813 BID_RETURN (res);
816 diff = exp_x - exp_y;
818 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
819 if (diff > 0) { // to simplify the loop below,
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
827 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
828 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
848 //else { //128 by 64 bit multiply -> 192 bits
849 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
868 diff = exp_y - exp_x;
870 // if exp_x is 33 less than exp_y, no need for compensation
871 if (diff > 33) {
872 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
873 BID_RETURN (res);
876 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
877 // adjust the y significand upwards
878 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
903 // if postitive, return whichever significand is larger
904 // (converse if negative)
905 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
906 && (sig_n_prime192.w[0] == sig_x.w[0])) {
907 res = 0;
908 BID_RETURN (res);
909 } // if equal, return 0
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);
920 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_less, x, y)
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;
930 // NaN (CASE1)
931 // if either number is NAN, the comparison is unordered,
932 // rather than equal : return 0
933 if (((x.w[1] & MASK_NAN) == MASK_NAN)
934 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
935 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
936 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
937 *pfpsf |= INVALID_EXCEPTION;
940 res = 0;
941 BID_RETURN (res);
944 // SIMPLE (CASE2)
945 // if all the bits are the same, these numbers are equal.
946 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
947 res = 0;
948 BID_RETURN (res);
950 // INFINITY (CASE3)
951 if ((x.w[1] & MASK_INF) == MASK_INF) {
952 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
953 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
954 // x is -inf, so it is less than y unless y is -inf
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
962 res = 0;
963 BID_RETURN (res);
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
969 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
970 BID_RETURN (res);
973 // CONVERT X
974 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
975 sig_x.w[0] = x.w[0];
976 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
978 // CHECK IF X IS CANONICAL
979 // 9999999999999999999999999999999999(decimal) =
980 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
981 // [0, 10^34) is the 754r supported canonical range.
982 // If the value exceeds that, it is interpreted as 0.
983 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
984 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
985 && (sig_x.w[0] > 0x378d8e63ffffffffull))
986 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
987 non_canon_x = 1;
988 else
989 non_canon_x = 0;
991 // CONVERT Y
992 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
993 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
994 sig_y.w[0] = y.w[0];
996 // CHECK IF Y IS CANONICAL
997 // 9999999999999999999999999999999999(decimal) =
998 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
999 // [0, 10^34) is the 754r supported canonical range.
1000 // If the value exceeds that, it is interpreted as 0.
1001 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1002 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1003 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1004 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1005 non_canon_y = 1;
1006 else
1007 non_canon_y = 0;
1009 // ZERO (CASE4)
1010 // some properties:
1011 // (+ZERO == -ZERO) => therefore ignore the sign
1012 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1013 // ignore the exponent field
1014 // (Any non-canonical # is considered 0)
1015 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1016 x_is_zero = 1;
1018 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1019 y_is_zero = 1;
1021 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
1022 if (x_is_zero && y_is_zero) {
1023 res = 0;
1024 BID_RETURN (res);
1026 // is x is zero, it is greater if Y is negative
1027 else if (x_is_zero) {
1028 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1029 BID_RETURN (res);
1031 // is y is zero, X is greater if it is positive
1032 else if (y_is_zero) {
1033 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1034 BID_RETURN (res);
1036 // OPPOSITE SIGN (CASE5)
1037 // now, if the sign bits differ, x is greater if y is negative
1038 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
1039 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1040 BID_RETURN (res);
1042 // REDUNDANT REPRESENTATIONS (CASE6)
1043 // if exponents are the same, then we have a simple comparison of the
1044 // significands
1045 if (exp_y == exp_x) {
1046 res = (((sig_x.w[1] > sig_y.w[1])
1047 || (sig_x.w[1] == sig_y.w[1]
1048 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
1049 MASK_SIGN));
1050 BID_RETURN (res);
1052 // if both components are either bigger or smaller,
1053 // it is clear what needs to be done
1054 if ((sig_x.w[1] > sig_y.w[1]
1055 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1056 && exp_x >= exp_y) {
1057 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1058 BID_RETURN (res);
1060 if ((sig_x.w[1] < sig_y.w[1]
1061 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1062 && exp_x <= exp_y) {
1063 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1064 BID_RETURN (res);
1067 diff = exp_x - exp_y;
1069 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1070 if (diff > 0) { // to simplify the loop below,
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
1078 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1079 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
1099 //else { //128 by 64 bit multiply -> 192 bits
1100 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
1119 diff = exp_y - exp_x;
1121 // if exp_x is 33 less than exp_y, no need for compensation
1122 if (diff > 33) {
1123 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1124 BID_RETURN (res);
1127 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1128 // adjust the y significand upwards
1129 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
1153 // if postitive, return whichever significand is larger
1154 // (converse if negative)
1155 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
1156 && (sig_n_prime192.w[0] == sig_x.w[0])) {
1157 res = 0;
1158 BID_RETURN (res);
1159 } // if equal, return 0
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);
1170 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_less_equal,
1171 x, y)
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;
1181 // NaN (CASE1)
1182 // if either number is NAN, the comparison is unordered,
1183 // rather than equal : return 0
1184 if (((x.w[1] & MASK_NAN) == MASK_NAN)
1185 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
1186 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
1187 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
1188 *pfpsf |= INVALID_EXCEPTION;
1191 res = 0;
1192 BID_RETURN (res);
1195 // SIMPLE (CASE2)
1196 // if all the bits are the same, these numbers are equal (not Greater).
1197 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
1198 res = 1;
1199 BID_RETURN (res);
1201 // INFINITY (CASE3)
1202 if ((x.w[1] & MASK_INF) == MASK_INF) {
1203 // if x is neg infinity, there is no way it is greater than y, return 1
1204 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
1205 res = 1;
1206 BID_RETURN (res);
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);
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
1219 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1220 BID_RETURN (res);
1223 // CONVERT X
1224 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1225 sig_x.w[0] = x.w[0];
1226 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1228 // CHECK IF X IS CANONICAL
1229 // 9999999999999999999999999999999999(decimal) =
1230 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1231 // [0, 10^34) is the 754r supported canonical range.
1232 // If the value exceeds that, it is interpreted as 0.
1233 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
1234 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
1235 && (sig_x.w[0] > 0x378d8e63ffffffffull))
1236 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1237 non_canon_x = 1;
1238 else
1239 non_canon_x = 0;
1241 // CONVERT Y
1242 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1243 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1244 sig_y.w[0] = y.w[0];
1246 // CHECK IF Y IS CANONICAL
1247 // 9999999999999999999999999999999999(decimal) =
1248 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1249 // [0, 10^34) is the 754r supported canonical range.
1250 // If the value exceeds that, it is interpreted as 0.
1251 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1252 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1253 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1254 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1255 non_canon_y = 1;
1256 else
1257 non_canon_y = 0;
1259 // ZERO (CASE4)
1260 // some properties:
1261 // (+ZERO == -ZERO) => therefore ignore the sign
1262 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1263 // ignore the exponent field
1264 // (Any non-canonical # is considered 0)
1265 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1266 x_is_zero = 1;
1268 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1269 y_is_zero = 1;
1271 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
1272 if (x_is_zero && y_is_zero) {
1273 res = 1;
1274 BID_RETURN (res);
1276 // is x is zero, it is greater if Y is negative
1277 else if (x_is_zero) {
1278 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1279 BID_RETURN (res);
1281 // is y is zero, X is greater if it is positive
1282 else if (y_is_zero) {
1283 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1284 BID_RETURN (res);
1286 // OPPOSITE SIGN (CASE5)
1287 // now, if the sign bits differ, x is greater if y is negative
1288 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
1289 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1290 BID_RETURN (res);
1292 // REDUNDANT REPRESENTATIONS (CASE6)
1293 // if exponents are the same, then we have a simple comparison of the
1294 // significands
1295 if (exp_y == exp_x) {
1296 res = (((sig_x.w[1] > sig_y.w[1]) || (sig_x.w[1] == sig_y.w[1] &&
1297 sig_x.w[0] >=
1298 sig_y.w[0])) ^ ((x.
1299 w[1] &
1300 MASK_SIGN) !=
1301 MASK_SIGN));
1302 BID_RETURN (res);
1304 // if both components are either bigger or smaller,
1305 // it is clear what needs to be done
1306 if ((sig_x.w[1] > sig_y.w[1]
1307 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1308 && exp_x >= exp_y) {
1309 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1310 BID_RETURN (res);
1312 if ((sig_x.w[1] < sig_y.w[1]
1313 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1314 && exp_x <= exp_y) {
1315 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1316 BID_RETURN (res);
1319 diff = exp_x - exp_y;
1321 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1322 if (diff > 0) { // to simplify the loop below,
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
1330 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1331 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
1351 //else { //128 by 64 bit multiply -> 192 bits
1352 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
1371 diff = exp_y - exp_x;
1373 // if exp_x is 33 less than exp_y, no need for compensation
1374 if (diff > 33) {
1375 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1376 BID_RETURN (res);
1379 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1380 // adjust the y significand upwards
1381 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
1406 // if postitive, return whichever significand is larger
1407 // (converse if negative)
1408 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
1409 && (sig_n_prime192.w[0] == sig_x.w[0])) {
1410 res = 1;
1411 BID_RETURN (res);
1412 } // if equal, return 0
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);
1423 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
1424 bid128_quiet_less_unordered,
1425 x, y)
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;
1435 // NaN (CASE1)
1436 // if either number is NAN, the comparison is unordered
1437 if (((x.w[1] & MASK_NAN) == MASK_NAN)
1438 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
1439 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
1440 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
1441 *pfpsf |= INVALID_EXCEPTION;
1444 res = 1;
1445 BID_RETURN (res);
1448 // SIMPLE (CASE2)
1449 // if all the bits are the same, these numbers are equal.
1450 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
1451 res = 0;
1452 BID_RETURN (res);
1454 // INFINITY (CASE3)
1455 if ((x.w[1] & MASK_INF) == MASK_INF) {
1456 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
1457 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
1458 // x is -inf, so it is less than y unless y is -inf
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
1466 res = 0;
1467 BID_RETURN (res);
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
1473 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1474 BID_RETURN (res);
1477 // CONVERT X
1478 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1479 sig_x.w[0] = x.w[0];
1480 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1482 // CHECK IF X IS CANONICAL
1483 // 9999999999999999999999999999999999(decimal) =
1484 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1485 // [0, 10^34) is the 754r supported canonical range.
1486 // If the value exceeds that, it is interpreted as 0.
1487 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
1488 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
1489 && (sig_x.w[0] > 0x378d8e63ffffffffull))
1490 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1491 non_canon_x = 1;
1492 else
1493 non_canon_x = 0;
1495 // CONVERT Y
1496 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1497 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1498 sig_y.w[0] = y.w[0];
1500 // CHECK IF Y IS CANONICAL
1501 // 9999999999999999999999999999999999(decimal) =
1502 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1503 // [0, 10^34) is the 754r supported canonical range.
1504 // If the value exceeds that, it is interpreted as 0.
1505 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1506 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1507 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1508 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1509 non_canon_y = 1;
1510 else
1511 non_canon_y = 0;
1513 // ZERO (CASE4)
1514 // some properties:
1515 // (+ZERO == -ZERO) => therefore ignore the sign
1516 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1517 // ignore the exponent field
1518 // (Any non-canonical # is considered 0)
1519 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1520 x_is_zero = 1;
1522 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1523 y_is_zero = 1;
1525 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
1526 if (x_is_zero && y_is_zero) {
1527 res = 0;
1528 BID_RETURN (res);
1530 // is x is zero, it is greater if Y is negative
1531 else if (x_is_zero) {
1532 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1533 BID_RETURN (res);
1535 // is y is zero, X is greater if it is positive
1536 else if (y_is_zero) {
1537 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1538 BID_RETURN (res);
1540 // OPPOSITE SIGN (CASE5)
1541 // now, if the sign bits differ, x is greater if y is negative
1542 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
1543 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1544 BID_RETURN (res);
1546 // REDUNDANT REPRESENTATIONS (CASE6)
1547 // if exponents are the same, then we have a simple comparison
1548 // of the significands
1549 if (exp_y == exp_x) {
1550 res = (((sig_x.w[1] > sig_y.w[1])
1551 || (sig_x.w[1] == sig_y.w[1]
1552 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
1553 MASK_SIGN));
1554 BID_RETURN (res);
1556 // if both components are either bigger or smaller,
1557 // it is clear what needs to be done
1558 if ((sig_x.w[1] > sig_y.w[1]
1559 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1560 && exp_x >= exp_y) {
1561 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1562 BID_RETURN (res);
1564 if ((sig_x.w[1] < sig_y.w[1]
1565 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1566 && exp_x <= exp_y) {
1567 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1568 BID_RETURN (res);
1571 diff = exp_x - exp_y;
1573 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1574 if (diff > 0) { // to simplify the loop below,
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
1582 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1583 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
1603 //else { //128 by 64 bit multiply -> 192 bits
1604 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
1623 diff = exp_y - exp_x;
1625 // if exp_x is 33 less than exp_y, no need for compensation
1626 if (diff > 33) {
1627 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1628 BID_RETURN (res);
1631 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1632 // adjust the y significand upwards
1633 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
1658 // if postitive, return whichever significand is larger
1659 // (converse if negative)
1660 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
1661 && (sig_n_prime192.w[0] == sig_x.w[0])) {
1662 res = 0;
1663 BID_RETURN (res);
1664 } // if equal, return 0
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);
1675 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_not_equal,
1676 x, y)
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;
1685 // NaN (CASE1)
1686 // if either number is NAN, the comparison is unordered,
1687 // rather than equal : return 0
1688 if (((x.w[1] & MASK_NAN) == MASK_NAN)
1689 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
1690 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
1691 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
1692 *pfpsf |= INVALID_EXCEPTION;
1695 res = 1;
1696 BID_RETURN (res);
1699 // SIMPLE (CASE2)
1700 // if all the bits are the same, these numbers are equivalent.
1701 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
1702 res = 0;
1703 BID_RETURN (res);
1705 // INFINITY (CASE3)
1706 if ((x.w[1] & MASK_INF) == MASK_INF) {
1707 if ((y.w[1] & MASK_INF) == MASK_INF) {
1708 res = (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN);
1709 BID_RETURN (res);
1710 } else {
1711 res = 1;
1712 BID_RETURN (res);
1715 if ((y.w[1] & MASK_INF) == MASK_INF) {
1716 res = 1;
1717 BID_RETURN (res);
1719 // CONVERT X
1720 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1721 sig_x.w[0] = x.w[0];
1722 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1724 // CHECK IF X IS CANONICAL
1725 // 9999999999999999999999999999999999(decimal) =
1726 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1727 // [0, 10^34) is the 754r supported canonical range.
1728 // If the value exceeds that, it is interpreted as 0.
1729 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
1730 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
1731 && (sig_x.w[0] > 0x378d8e63ffffffffull))
1732 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1733 non_canon_x = 1;
1734 else
1735 non_canon_x = 0;
1737 // CONVERT Y
1738 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1739 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1740 sig_y.w[0] = y.w[0];
1742 // CHECK IF Y IS CANONICAL
1743 // 9999999999999999999999999999999999(decimal) =
1744 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1745 // [0, 10^34) is the 754r supported canonical range.
1746 // If the value exceeds that, it is interpreted as 0.
1747 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1748 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1749 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1750 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1751 non_canon_y = 1;
1752 else
1753 non_canon_y = 0;
1755 // some properties:
1756 // (+ZERO == -ZERO) => therefore ignore the sign
1757 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1758 // ignore the exponent field
1759 // (Any non-canonical # is considered 0)
1760 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1761 x_is_zero = 1;
1763 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1764 y_is_zero = 1;
1767 if (x_is_zero && y_is_zero) {
1768 res = 0;
1769 BID_RETURN (res);
1770 } else if ((x_is_zero && !y_is_zero) || (!x_is_zero && y_is_zero)) {
1771 res = 1;
1772 BID_RETURN (res);
1774 // OPPOSITE SIGN (CASE5)
1775 // now, if the sign bits differ => not equal : return 0
1776 if ((x.w[1] ^ y.w[1]) & MASK_SIGN) {
1777 res = 1;
1778 BID_RETURN (res);
1780 // REDUNDANT REPRESENTATIONS (CASE6)
1781 if (exp_x > exp_y) { // to simplify the loop below,
1782 SWAP (exp_x, exp_y, exp_t); // put the larger exp in y,
1783 SWAP (sig_x.w[1], sig_y.w[1], sig_t.w[1]); // and the smaller exp in x
1784 SWAP (sig_x.w[0], sig_y.w[0], sig_t.w[0]); // and the smaller exp in x
1788 if (exp_y - exp_x > 33) {
1789 res = 1;
1790 BID_RETURN (res);
1791 } // difference cannot be greater than 10^33
1793 if (exp_y - exp_x > 19) {
1794 // recalculate y's significand upwards
1795 __mul_128x128_to_256 (sig_n_prime256, sig_y,
1796 ten2k128[exp_y - exp_x - 20]);
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);
1805 //else{
1806 // recalculate y's significand upwards
1807 __mul_64x128_to192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y);
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);
1816 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_not_greater,
1817 x, y)
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;
1827 // NaN (CASE1)
1828 // if either number is NAN, the comparison is unordered,
1829 // rather than equal : return 0
1830 if (((x.w[1] & MASK_NAN) == MASK_NAN)
1831 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
1832 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
1833 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
1834 *pfpsf |= INVALID_EXCEPTION;
1837 res = 1;
1838 BID_RETURN (res);
1841 // SIMPLE (CASE2)
1842 // if all the bits are the same, these numbers are equal (not Greater).
1843 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
1844 res = 1;
1845 BID_RETURN (res);
1847 // INFINITY (CASE3)
1848 if ((x.w[1] & MASK_INF) == MASK_INF) {
1849 // if x is neg infinity, there is no way it is greater than y, return 1
1850 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
1851 res = 1;
1852 BID_RETURN (res);
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);
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
1864 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1865 BID_RETURN (res);
1868 // CONVERT X
1869 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1870 sig_x.w[0] = x.w[0];
1871 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1873 // CHECK IF X IS CANONICAL
1874 // 9999999999999999999999999999999999(decimal) =
1875 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1876 // [0, 10^34) is the 754r supported canonical range.
1877 // If the value exceeds that, it is interpreted as 0.
1878 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
1879 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
1880 && (sig_x.w[0] > 0x378d8e63ffffffffull))
1881 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1882 non_canon_x = 1;
1883 else
1884 non_canon_x = 0;
1886 // CONVERT Y
1887 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1888 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1889 sig_y.w[0] = y.w[0];
1891 // CHECK IF Y IS CANONICAL
1892 // 9999999999999999999999999999999999(decimal) =
1893 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1894 // [0, 10^34) is the 754r supported canonical range.
1895 // If the value exceeds that, it is interpreted as 0.
1896 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1897 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1898 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1899 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1900 non_canon_y = 1;
1901 else
1902 non_canon_y = 0;
1904 // ZERO (CASE4)
1905 // some properties:
1906 // (+ZERO == -ZERO) => therefore ignore the sign
1907 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1908 // ignore the exponent field
1909 // (Any non-canonical # is considered 0)
1910 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1911 x_is_zero = 1;
1913 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1914 y_is_zero = 1;
1916 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
1917 if (x_is_zero && y_is_zero) {
1918 res = 1;
1919 BID_RETURN (res);
1921 // is x is zero, it is greater if Y is negative
1922 else if (x_is_zero) {
1923 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1924 BID_RETURN (res);
1926 // is y is zero, X is greater if it is positive
1927 else if (y_is_zero) {
1928 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1929 BID_RETURN (res);
1931 // OPPOSITE SIGN (CASE5)
1932 // now, if the sign bits differ, x is greater if y is negative
1933 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
1934 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1935 BID_RETURN (res);
1937 // REDUNDANT REPRESENTATIONS (CASE6)
1938 // if exponents are the same, then we have a simple comparison
1939 // of the significands
1940 if (exp_y == exp_x) {
1941 res = (((sig_x.w[1] > sig_y.w[1])
1942 || (sig_x.w[1] == sig_y.w[1]
1943 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
1944 MASK_SIGN));
1945 BID_RETURN (res);
1947 // if both components are either bigger or smaller,
1948 // it is clear what needs to be done
1949 if ((sig_x.w[1] > sig_y.w[1]
1950 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1951 && exp_x >= exp_y) {
1952 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1953 BID_RETURN (res);
1955 if ((sig_x.w[1] < sig_y.w[1]
1956 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1957 && exp_x <= exp_y) {
1958 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1959 BID_RETURN (res);
1962 diff = exp_x - exp_y;
1964 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1965 if (diff > 0) { // to simplify the loop below,
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
1973 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1974 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
1994 //else { //128 by 64 bit multiply -> 192 bits
1995 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
2014 diff = exp_y - exp_x;
2016 // if exp_x is 33 less than exp_y, no need for compensation
2017 if (diff > 33) {
2018 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2019 BID_RETURN (res);
2022 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2023 // adjust the y significand upwards
2024 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
2049 // if postitive, return whichever significand is larger
2050 // (converse if negative)
2051 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
2052 && (sig_n_prime192.w[0] == sig_x.w[0])) {
2053 res = 1;
2054 BID_RETURN (res);
2055 } // if equal, return 0
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);
2066 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_not_less, x,
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;
2077 // NaN (CASE1)
2078 // if either number is NAN, the comparison is unordered,
2079 // rather than equal : return 1
2080 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2081 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2082 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
2083 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
2084 *pfpsf |= INVALID_EXCEPTION;
2087 res = 1;
2088 BID_RETURN (res);
2091 // SIMPLE (CASE2)
2092 // if all the bits are the same, these numbers are equal (not Greater).
2093 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
2094 res = 1;
2095 BID_RETURN (res);
2097 // INFINITY (CASE3)
2098 if ((x.w[1] & MASK_INF) == MASK_INF) {
2099 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
2100 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
2101 // x is -inf, so it is less than y unless y is -inf
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
2109 res = 1;
2110 BID_RETURN (res);
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
2116 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2117 BID_RETURN (res);
2120 // CONVERT X
2121 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
2122 sig_x.w[0] = x.w[0];
2123 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
2125 // CHECK IF X IS CANONICAL
2126 // 9999999999999999999999999999999999(decimal) =
2127 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2128 // [0, 10^34) is the 754r supported canonical range.
2129 // If the value exceeds that, it is interpreted as 0.
2130 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
2131 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
2132 && (sig_x.w[0] > 0x378d8e63ffffffffull))
2133 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2134 non_canon_x = 1;
2135 else
2136 non_canon_x = 0;
2138 // CONVERT Y
2139 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
2140 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
2141 sig_y.w[0] = y.w[0];
2143 // CHECK IF Y IS CANONICAL
2144 // 9999999999999999999999999999999999(decimal) =
2145 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2146 // [0, 10^34) is the 754r supported canonical range.
2147 // If the value exceeds that, it is interpreted as 0.
2148 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
2149 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
2150 && (sig_y.w[0] > 0x378d8e63ffffffffull))
2151 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2152 non_canon_y = 1;
2153 else
2154 non_canon_y = 0;
2156 // ZERO (CASE4)
2157 // some properties:
2158 // (+ZERO == -ZERO) => therefore ignore the sign
2159 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
2160 // ignore the exponent field
2161 // (Any non-canonical # is considered 0)
2162 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
2163 x_is_zero = 1;
2165 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
2166 y_is_zero = 1;
2168 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
2169 if (x_is_zero && y_is_zero) {
2170 res = 1;
2171 BID_RETURN (res);
2173 // is x is zero, it is greater if Y is negative
2174 else if (x_is_zero) {
2175 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2176 BID_RETURN (res);
2178 // is y is zero, X is greater if it is positive
2179 else if (y_is_zero) {
2180 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2181 BID_RETURN (res);
2183 // OPPOSITE SIGN (CASE5)
2184 // now, if the sign bits differ, x is greater if y is negative
2185 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
2186 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2187 BID_RETURN (res);
2189 // REDUNDANT REPRESENTATIONS (CASE6)
2191 // if exponents are the same, then we have a simple comparison
2192 // of the significands
2193 if (exp_y == exp_x) {
2194 res = (((sig_x.w[1] > sig_y.w[1])
2195 || (sig_x.w[1] == sig_y.w[1]
2196 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
2197 MASK_SIGN));
2198 BID_RETURN (res);
2200 // if both components are either bigger or smaller,
2201 // it is clear what needs to be done
2202 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
2203 && exp_x > exp_y) {
2204 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2205 BID_RETURN (res);
2207 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
2208 && exp_x < exp_y) {
2209 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2210 BID_RETURN (res);
2213 diff = exp_x - exp_y;
2215 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
2216 if (diff > 0) { // to simplify the loop below,
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
2224 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2225 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
2245 //else { //128 by 64 bit multiply -> 192 bits
2246 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
2265 diff = exp_y - exp_x;
2267 // if exp_x is 33 less than exp_y, no need for compensation
2268 if (diff > 33) {
2269 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2270 BID_RETURN (res);
2273 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2274 // adjust the y significand upwards
2275 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
2300 // if postitive, return whichever significand is larger
2301 // (converse if negative)
2302 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
2303 && (sig_n_prime192.w[0] == sig_x.w[0])) {
2304 res = 1;
2305 BID_RETURN (res);
2306 } // if equal, return 1
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);
2317 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_ordered, x,
2320 int res;
2322 // NaN (CASE1)
2323 // if either number is NAN, the comparison is ordered : return 1
2324 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2325 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2326 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
2327 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
2328 *pfpsf |= INVALID_EXCEPTION;
2331 res = 0;
2332 BID_RETURN (res);
2336 res = 1;
2337 BID_RETURN (res);
2341 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_unordered,
2342 x, y)
2344 int res;
2346 // NaN (CASE1)
2347 // if either number is NAN, the comparison is unordered : return 1
2348 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2349 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2350 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
2351 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
2352 *pfpsf |= INVALID_EXCEPTION;
2355 res = 1;
2356 BID_RETURN (res);
2360 res = 0;
2361 BID_RETURN (res);
2365 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_signaling_greater,
2366 x, y)
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;
2376 // NaN (CASE1)
2377 // if either number is NAN, the comparison is unordered,
2378 // rather than equal : return 0
2379 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2380 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2381 *pfpsf |= INVALID_EXCEPTION;
2383 res = 0;
2384 BID_RETURN (res);
2387 // SIMPLE (CASE2)
2388 // if all the bits are the same, these numbers are equal (not Greater).
2389 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
2390 res = 0;
2391 BID_RETURN (res);
2393 // INFINITY (CASE3)
2394 if ((x.w[1] & MASK_INF) == MASK_INF) {
2395 // if x is neg infinity, there is no way it is greater than y, return 0
2396 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
2397 res = 0;
2398 BID_RETURN (res);
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);
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
2410 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2411 BID_RETURN (res);
2414 // CONVERT X
2415 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
2416 sig_x.w[0] = x.w[0];
2417 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
2419 // CHECK IF X IS CANONICAL
2420 // 9999999999999999999999999999999999(decimal) =
2421 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2422 // [0, 10^34) is the 754r supported canonical range.
2423 // If the value exceeds that, it is interpreted as 0.
2424 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
2425 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
2426 && (sig_x.w[0] > 0x378d8e63ffffffffull))
2427 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2428 non_canon_x = 1;
2429 else
2430 non_canon_x = 0;
2432 // CONVERT Y
2433 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
2434 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
2435 sig_y.w[0] = y.w[0];
2437 // CHECK IF Y IS CANONICAL
2438 // 9999999999999999999999999999999999(decimal) =
2439 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2440 // [0, 10^34) is the 754r supported canonical range.
2441 // If the value exceeds that, it is interpreted as 0.
2442 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
2443 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
2444 && (sig_y.w[0] > 0x378d8e63ffffffffull))
2445 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2446 non_canon_y = 1;
2447 else
2448 non_canon_y = 0;
2450 // ZERO (CASE4)
2451 // some properties:
2452 // (+ZERO == -ZERO) => therefore ignore the sign
2453 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
2454 // ignore the exponent field
2455 // (Any non-canonical # is considered 0)
2456 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
2457 x_is_zero = 1;
2459 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
2460 y_is_zero = 1;
2462 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
2463 if (x_is_zero && y_is_zero) {
2464 res = 0;
2465 BID_RETURN (res);
2467 // is x is zero, it is greater if Y is negative
2468 else if (x_is_zero) {
2469 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2470 BID_RETURN (res);
2472 // is y is zero, X is greater if it is positive
2473 else if (y_is_zero) {
2474 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2475 BID_RETURN (res);
2477 // OPPOSITE SIGN (CASE5)
2478 // now, if the sign bits differ, x is greater if y is negative
2479 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
2480 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2481 BID_RETURN (res);
2483 // REDUNDANT REPRESENTATIONS (CASE6)
2484 // if exponents are the same, then we have a simple comparison
2485 // of the significands
2486 if (exp_y == exp_x) {
2487 res = (((sig_x.w[1] > sig_y.w[1])
2488 || (sig_x.w[1] == sig_y.w[1]
2489 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
2490 MASK_SIGN));
2491 BID_RETURN (res);
2493 // if both components are either bigger or smaller,
2494 // it is clear what needs to be done
2495 if ((sig_x.w[1] > sig_y.w[1]
2496 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
2497 && exp_x >= exp_y) {
2499 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2500 BID_RETURN (res);
2503 if ((sig_x.w[1] < sig_y.w[1]
2504 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
2505 && exp_x <= exp_y) {
2507 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2508 BID_RETURN (res);
2512 diff = exp_x - exp_y;
2514 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
2515 if (diff > 0) { // to simplify the loop below,
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
2523 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2524 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
2543 //else { //128 by 64 bit multiply -> 192 bits
2544 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
2563 diff = exp_y - exp_x;
2565 // if exp_x is 33 less than exp_y, no need for compensation
2566 if (diff > 33) {
2567 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2568 BID_RETURN (res);
2571 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2572 // adjust the y significand upwards
2573 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
2597 // if postitive, return whichever significand is larger
2598 // (converse if negative)
2599 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
2600 && (sig_n_prime192.w[0] == sig_x.w[0])) {
2601 res = 0;
2602 BID_RETURN (res);
2603 } // if equal, return 0
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);
2614 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
2615 bid128_signaling_greater_equal,
2616 x, y)
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;
2626 // NaN (CASE1)
2627 // if either number is NAN, the comparison is unordered,
2628 // rather than equal : return 1
2629 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2630 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2631 *pfpsf |= INVALID_EXCEPTION;
2633 res = 0;
2634 BID_RETURN (res);
2637 // SIMPLE (CASE2)
2638 // if all the bits are the same, these numbers are equal (not Greater).
2639 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
2640 res = 1;
2641 BID_RETURN (res);
2643 // INFINITY (CASE3)
2644 if ((x.w[1] & MASK_INF) == MASK_INF) {
2645 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
2646 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
2647 // x is -inf, so it is less than y unless y is -inf
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
2655 res = 1;
2656 BID_RETURN (res);
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
2662 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2663 BID_RETURN (res);
2666 // CONVERT X
2667 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
2668 sig_x.w[0] = x.w[0];
2669 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
2671 // CHECK IF X IS CANONICAL
2672 // 9999999999999999999999999999999999(decimal) =
2673 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2674 // [0, 10^34) is the 754r supported canonical range.
2675 // If the value exceeds that, it is interpreted as 0.
2676 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
2677 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
2678 && (sig_x.w[0] > 0x378d8e63ffffffffull))
2679 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2680 non_canon_x = 1;
2681 else
2682 non_canon_x = 0;
2684 // CONVERT Y
2685 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
2686 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
2687 sig_y.w[0] = y.w[0];
2689 // CHECK IF Y IS CANONICAL
2690 // 9999999999999999999999999999999999(decimal) =
2691 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2692 // [0, 10^34) is the 754r supported canonical range.
2693 // If the value exceeds that, it is interpreted as 0.
2694 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
2695 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
2696 && (sig_y.w[0] > 0x378d8e63ffffffffull))
2697 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2698 non_canon_y = 1;
2699 else
2700 non_canon_y = 0;
2702 // ZERO (CASE4)
2703 // some properties:
2704 // (+ZERO == -ZERO) => therefore ignore the sign
2705 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
2706 // ignore the exponent field
2707 // (Any non-canonical # is considered 0)
2708 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
2709 x_is_zero = 1;
2711 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
2712 y_is_zero = 1;
2714 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
2715 if (x_is_zero && y_is_zero) {
2716 res = 1;
2717 BID_RETURN (res);
2719 // is x is zero, it is greater if Y is negative
2720 else if (x_is_zero) {
2721 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2722 BID_RETURN (res);
2724 // is y is zero, X is greater if it is positive
2725 else if (y_is_zero) {
2726 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2727 BID_RETURN (res);
2729 // OPPOSITE SIGN (CASE5)
2730 // now, if the sign bits differ, x is greater if y is negative
2731 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
2732 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2733 BID_RETURN (res);
2735 // REDUNDANT REPRESENTATIONS (CASE6)
2736 // if exponents are the same, then we have a simple comparison
2737 // of the significands
2738 if (exp_y == exp_x) {
2739 res = (((sig_x.w[1] > sig_y.w[1])
2740 || (sig_x.w[1] == sig_y.w[1]
2741 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
2742 MASK_SIGN));
2743 BID_RETURN (res);
2745 // if both components are either bigger or smaller,
2746 // it is clear what needs to be done
2747 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
2748 && exp_x > exp_y) {
2749 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2750 BID_RETURN (res);
2752 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
2753 && exp_x < exp_y) {
2754 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2755 BID_RETURN (res);
2758 diff = exp_x - exp_y;
2760 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
2761 if (diff > 0) { // to simplify the loop below,
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
2769 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2770 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
2790 //else { //128 by 64 bit multiply -> 192 bits
2791 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
2810 diff = exp_y - exp_x;
2812 // if exp_x is 33 less than exp_y, no need for compensation
2813 if (diff > 33) {
2814 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2815 BID_RETURN (res);
2818 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2819 // adjust the y significand upwards
2820 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
2845 // if postitive, return whichever significand is larger
2846 // (converse if negative)
2847 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
2848 && (sig_n_prime192.w[0] == sig_x.w[0])) {
2849 res = 1;
2850 BID_RETURN (res);
2851 } // if equal, return 1
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);
2862 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
2863 bid128_signaling_greater_unordered,
2864 x, y)
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;
2874 // NaN (CASE1)
2875 // if either number is NAN, the comparison is unordered,
2876 // rather than equal : return 1
2877 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2878 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2879 *pfpsf |= INVALID_EXCEPTION;
2881 res = 1;
2882 BID_RETURN (res);
2885 // SIMPLE (CASE2)
2886 // if all the bits are the same, these numbers are equal (not Greater).
2887 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
2888 res = 0;
2889 BID_RETURN (res);
2891 // INFINITY (CASE3)
2892 if ((x.w[1] & MASK_INF) == MASK_INF) {
2893 // if x is neg infinity, there is no way it is greater than y, return 0
2894 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
2895 res = 0;
2896 BID_RETURN (res);
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);
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
2908 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2909 BID_RETURN (res);
2912 // CONVERT X
2913 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
2914 sig_x.w[0] = x.w[0];
2915 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
2917 // CHECK IF X IS CANONICAL
2918 // 9999999999999999999999999999999999(decimal) =
2919 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2920 // [0, 10^34) is the 754r supported canonical range.
2921 // If the value exceeds that, it is interpreted as 0.
2922 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
2923 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
2924 && (sig_x.w[0] > 0x378d8e63ffffffffull))
2925 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2926 non_canon_x = 1;
2927 else
2928 non_canon_x = 0;
2930 // CONVERT Y
2931 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
2932 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
2933 sig_y.w[0] = y.w[0];
2935 // CHECK IF Y IS CANONICAL
2936 // 9999999999999999999999999999999999(decimal) =
2937 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2938 // [0, 10^34) is the 754r supported canonical range.
2939 // If the value exceeds that, it is interpreted as 0.
2940 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
2941 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
2942 && (sig_y.w[0] > 0x378d8e63ffffffffull))
2943 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2944 non_canon_y = 1;
2945 else
2946 non_canon_y = 0;
2948 // ZERO (CASE4)
2949 // some properties:
2950 // (+ZERO == -ZERO) => therefore ignore the sign
2951 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
2952 // ignore the exponent field
2953 // (Any non-canonical # is considered 0)
2954 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
2955 x_is_zero = 1;
2957 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
2958 y_is_zero = 1;
2960 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
2961 if (x_is_zero && y_is_zero) {
2962 res = 0;
2963 BID_RETURN (res);
2965 // is x is zero, it is greater if Y is negative
2966 else if (x_is_zero) {
2967 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2968 BID_RETURN (res);
2970 // is y is zero, X is greater if it is positive
2971 else if (y_is_zero) {
2972 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2973 BID_RETURN (res);
2975 // OPPOSITE SIGN (CASE5)
2976 // now, if the sign bits differ, x is greater if y is negative
2977 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
2978 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2979 BID_RETURN (res);
2981 // REDUNDANT REPRESENTATIONS (CASE6)
2982 // if exponents are the same, then we have a simple comparison
2983 // of the significands
2984 if (exp_y == exp_x) {
2985 res = (((sig_x.w[1] > sig_y.w[1])
2986 || (sig_x.w[1] == sig_y.w[1]
2987 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
2988 MASK_SIGN));
2989 BID_RETURN (res);
2991 // if both components are either bigger or smaller,
2992 // it is clear what needs to be done
2993 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
2994 && exp_x > exp_y) {
2995 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2996 BID_RETURN (res);
2998 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
2999 && exp_x < exp_y) {
3000 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3001 BID_RETURN (res);
3004 diff = exp_x - exp_y;
3006 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
3007 if (diff > 0) { // to simplify the loop below,
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
3015 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3016 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
3036 //else { //128 by 64 bit multiply -> 192 bits
3037 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
3056 diff = exp_y - exp_x;
3058 // if exp_x is 33 less than exp_y, no need for compensation
3059 if (diff > 33) {
3060 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3061 BID_RETURN (res);
3064 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3065 // adjust the y significand upwards
3066 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
3091 // if postitive, return whichever significand is larger
3092 // (converse if negative)
3093 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
3094 && (sig_n_prime192.w[0] == sig_x.w[0])) {
3095 res = 0;
3096 BID_RETURN (res);
3097 } // if equal, return 0
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);
3108 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_signaling_less, x,
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;
3119 // NaN (CASE1)
3120 // if either number is NAN, the comparison is unordered,
3121 // rather than equal : return 0
3122 if (((x.w[1] & MASK_NAN) == MASK_NAN)
3123 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
3124 *pfpsf |= INVALID_EXCEPTION;
3126 res = 0;
3127 BID_RETURN (res);
3130 // SIMPLE (CASE2)
3131 // if all the bits are the same, these numbers are equal.
3132 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
3133 res = 0;
3134 BID_RETURN (res);
3136 // INFINITY (CASE3)
3137 if ((x.w[1] & MASK_INF) == MASK_INF) {
3138 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
3139 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
3140 // x is -inf, so it is less than y unless y is -inf
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
3148 res = 0;
3149 BID_RETURN (res);
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
3155 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3156 BID_RETURN (res);
3159 // CONVERT X
3160 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
3161 sig_x.w[0] = x.w[0];
3162 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
3164 // CHECK IF X IS CANONICAL
3165 // 9999999999999999999999999999999999(decimal) =
3166 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3167 // [0, 10^34) is the 754r supported canonical range.
3168 // If the value exceeds that, it is interpreted as 0.
3169 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
3170 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
3171 && (sig_x.w[0] > 0x378d8e63ffffffffull))
3172 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3173 non_canon_x = 1;
3174 else
3175 non_canon_x = 0;
3177 // CONVERT Y
3178 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
3179 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
3180 sig_y.w[0] = y.w[0];
3182 // CHECK IF Y IS CANONICAL
3183 // 9999999999999999999999999999999999(decimal) =
3184 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3185 // [0, 10^34) is the 754r supported canonical range.
3186 // If the value exceeds that, it is interpreted as 0.
3187 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
3188 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
3189 && (sig_y.w[0] > 0x378d8e63ffffffffull))
3190 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3191 non_canon_y = 1;
3192 else
3193 non_canon_y = 0;
3195 // ZERO (CASE4)
3196 // some properties:
3197 // (+ZERO == -ZERO) => therefore ignore the sign
3198 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
3199 // ignore the exponent field
3200 // (Any non-canonical # is considered 0)
3201 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
3202 x_is_zero = 1;
3204 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
3205 y_is_zero = 1;
3207 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
3208 if (x_is_zero && y_is_zero) {
3209 res = 0;
3210 BID_RETURN (res);
3212 // is x is zero, it is greater if Y is negative
3213 else if (x_is_zero) {
3214 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3215 BID_RETURN (res);
3217 // is y is zero, X is greater if it is positive
3218 else if (y_is_zero) {
3219 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3220 BID_RETURN (res);
3222 // OPPOSITE SIGN (CASE5)
3223 // now, if the sign bits differ, x is greater if y is negative
3224 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
3225 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3226 BID_RETURN (res);
3228 // REDUNDANT REPRESENTATIONS (CASE6)
3229 // if exponents are the same, then we have a simple comparison
3230 // of the significands
3231 if (exp_y == exp_x) {
3232 res = (((sig_x.w[1] > sig_y.w[1])
3233 || (sig_x.w[1] == sig_y.w[1]
3234 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
3235 MASK_SIGN));
3236 BID_RETURN (res);
3238 // if both components are either bigger or smaller,
3239 // it is clear what needs to be done
3240 if ((sig_x.w[1] > sig_y.w[1]
3241 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
3242 && exp_x >= exp_y) {
3243 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3244 BID_RETURN (res);
3246 if ((sig_x.w[1] < sig_y.w[1]
3247 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
3248 && exp_x <= exp_y) {
3249 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3250 BID_RETURN (res);
3253 diff = exp_x - exp_y;
3255 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
3256 if (diff > 0) { // to simplify the loop below,
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
3264 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3265 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
3285 //else { //128 by 64 bit multiply -> 192 bits
3286 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
3305 diff = exp_y - exp_x;
3307 // if exp_x is 33 less than exp_y, |x| < |y|, return 1 if positive
3308 if (diff > 33) {
3309 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3310 BID_RETURN (res);
3313 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3314 // adjust the y significand upwards
3315 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
3340 // if postitive, return whichever significand is larger
3341 // (converse if negative)
3342 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
3343 && (sig_n_prime192.w[0] == sig_x.w[0])) {
3344 res = 0;
3345 BID_RETURN (res);
3346 } // if equal, return 0
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);
3357 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
3358 bid128_signaling_less_equal,
3359 x, y)
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;
3369 // NaN (CASE1)
3370 // if either number is NAN, the comparison is unordered,
3371 // rather than equal : return 0
3372 if (((x.w[1] & MASK_NAN) == MASK_NAN)
3373 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
3374 *pfpsf |= INVALID_EXCEPTION;
3376 res = 0;
3377 BID_RETURN (res);
3380 // SIMPLE (CASE2)
3381 // if all the bits are the same, these numbers are equal (not Greater).
3382 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
3383 res = 1;
3384 BID_RETURN (res);
3386 // INFINITY (CASE3)
3387 if ((x.w[1] & MASK_INF) == MASK_INF) {
3388 // if x is neg infinity, there is no way it is greater than y, return 1
3389 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
3390 res = 1;
3391 BID_RETURN (res);
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);
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
3403 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3404 BID_RETURN (res);
3407 // CONVERT X
3408 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
3409 sig_x.w[0] = x.w[0];
3410 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
3412 // CHECK IF X IS CANONICAL
3413 // 9999999999999999999999999999999999(decimal) =
3414 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3415 // [0, 10^34) is the 754r supported canonical range.
3416 // If the value exceeds that, it is interpreted as 0.
3417 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
3418 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
3419 && (sig_x.w[0] > 0x378d8e63ffffffffull))
3420 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3421 non_canon_x = 1;
3422 else
3423 non_canon_x = 0;
3425 // CONVERT Y
3426 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
3427 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
3428 sig_y.w[0] = y.w[0];
3430 // CHECK IF Y IS CANONICAL
3431 // 9999999999999999999999999999999999(decimal) =
3432 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3433 // [0, 10^34) is the 754r supported canonical range.
3434 // If the value exceeds that, it is interpreted as 0.
3435 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
3436 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
3437 && (sig_y.w[0] > 0x378d8e63ffffffffull))
3438 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3439 non_canon_y = 1;
3440 else
3441 non_canon_y = 0;
3443 // ZERO (CASE4)
3444 // some properties:
3445 // (+ZERO == -ZERO) => therefore ignore the sign
3446 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
3447 // ignore the exponent field
3448 // (Any non-canonical # is considered 0)
3449 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
3450 x_is_zero = 1;
3452 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
3453 y_is_zero = 1;
3455 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
3456 if (x_is_zero && y_is_zero) {
3457 res = 1;
3458 BID_RETURN (res);
3460 // is x is zero, it is greater if Y is negative
3461 else if (x_is_zero) {
3462 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3463 BID_RETURN (res);
3465 // is y is zero, X is greater if it is positive
3466 else if (y_is_zero) {
3467 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3468 BID_RETURN (res);
3470 // OPPOSITE SIGN (CASE5)
3471 // now, if the sign bits differ, x is greater if y is negative
3472 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
3473 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3474 BID_RETURN (res);
3476 // REDUNDANT REPRESENTATIONS (CASE6)
3477 // if exponents are the same, then we have a simple comparison
3478 // of the significands
3479 if (exp_y == exp_x) {
3480 res = (((sig_x.w[1] > sig_y.w[1])
3481 || (sig_x.w[1] == sig_y.w[1]
3482 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
3483 MASK_SIGN));
3484 BID_RETURN (res);
3486 // if both components are either bigger or smaller,
3487 // it is clear what needs to be done
3488 if ((sig_x.w[1] > sig_y.w[1]
3489 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
3490 && exp_x >= exp_y) {
3491 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3492 BID_RETURN (res);
3494 if ((sig_x.w[1] < sig_y.w[1]
3495 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
3496 && exp_x <= exp_y) {
3497 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3498 BID_RETURN (res);
3501 diff = exp_x - exp_y;
3503 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
3504 if (diff > 0) { // to simplify the loop below,
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
3512 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3513 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
3533 //else { //128 by 64 bit multiply -> 192 bits
3534 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
3553 diff = exp_y - exp_x;
3555 // if exp_x is 33 less than exp_y, no need for compensation
3556 if (diff > 33) {
3557 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3558 BID_RETURN (res);
3561 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3562 // adjust the y significand upwards
3563 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
3588 // if postitive, return whichever significand is larger
3589 // (converse if negative)
3590 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
3591 && (sig_n_prime192.w[0] == sig_x.w[0])) {
3592 res = 1;
3593 BID_RETURN (res);
3594 } // if equal, return 0
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);
3605 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
3606 bid128_signaling_less_unordered,
3607 x, y)
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;
3617 // NaN (CASE1)
3618 // if either number is NAN, the comparison is unordered
3619 if (((x.w[1] & MASK_NAN) == MASK_NAN)
3620 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
3621 *pfpsf |= INVALID_EXCEPTION;
3623 res = 1;
3624 BID_RETURN (res);
3627 // SIMPLE (CASE2)
3628 // if all the bits are the same, these numbers are equal.
3629 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
3630 res = 0;
3631 BID_RETURN (res);
3633 // INFINITY (CASE3)
3634 if ((x.w[1] & MASK_INF) == MASK_INF) {
3635 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
3636 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
3637 // x is -inf, so it is less than y unless y is -inf
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
3645 res = 0;
3646 BID_RETURN (res);
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
3652 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3653 BID_RETURN (res);
3656 // CONVERT X
3657 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
3658 sig_x.w[0] = x.w[0];
3659 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
3661 // CHECK IF X IS CANONICAL
3662 // 9999999999999999999999999999999999(decimal) =
3663 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3664 // [0, 10^34) is the 754r supported canonical range.
3665 // If the value exceeds that, it is interpreted as 0.
3666 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
3667 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
3668 && (sig_x.w[0] > 0x378d8e63ffffffffull))
3669 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3670 non_canon_x = 1;
3671 else
3672 non_canon_x = 0;
3674 // CONVERT Y
3675 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
3676 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
3677 sig_y.w[0] = y.w[0];
3679 // CHECK IF Y IS CANONICAL
3680 // 9999999999999999999999999999999999(decimal) =
3681 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3682 // [0, 10^34) is the 754r supported canonical range.
3683 // If the value exceeds that, it is interpreted as 0.
3684 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
3685 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
3686 && (sig_y.w[0] > 0x378d8e63ffffffffull))
3687 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3688 non_canon_y = 1;
3689 else
3690 non_canon_y = 0;
3692 // ZERO (CASE4)
3693 // some properties:
3694 // (+ZERO == -ZERO) => therefore ignore the sign
3695 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
3696 // ignore the exponent field
3697 // (Any non-canonical # is considered 0)
3698 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
3699 x_is_zero = 1;
3701 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
3702 y_is_zero = 1;
3704 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
3705 if (x_is_zero && y_is_zero) {
3706 res = 0;
3707 BID_RETURN (res);
3709 // is x is zero, it is greater if Y is negative
3710 else if (x_is_zero) {
3711 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3712 BID_RETURN (res);
3714 // is y is zero, X is greater if it is positive
3715 else if (y_is_zero) {
3716 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3717 BID_RETURN (res);
3719 // OPPOSITE SIGN (CASE5)
3720 // now, if the sign bits differ, x is greater if y is negative
3721 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
3722 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3723 BID_RETURN (res);
3725 // REDUNDANT REPRESENTATIONS (CASE6)
3726 // if exponents are the same, then we have a simple comparison
3727 // of the significands
3728 if (exp_y == exp_x) {
3729 res = (((sig_x.w[1] > sig_y.w[1])
3730 || (sig_x.w[1] == sig_y.w[1]
3731 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
3732 MASK_SIGN));
3733 BID_RETURN (res);
3735 // if both components are either bigger or smaller,
3736 // it is clear what needs to be done
3737 if ((sig_x.w[1] > sig_y.w[1]
3738 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
3739 && exp_x >= exp_y) {
3740 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3741 BID_RETURN (res);
3743 if ((sig_x.w[1] < sig_y.w[1]
3744 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
3745 && exp_x <= exp_y) {
3746 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3747 BID_RETURN (res);
3750 diff = exp_x - exp_y;
3752 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
3753 if (diff > 0) { // to simplify the loop below,
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
3761 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3762 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
3782 //else { //128 by 64 bit multiply -> 192 bits
3783 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
3802 diff = exp_y - exp_x;
3804 // if exp_x is 33 less than exp_y, no need for compensation
3805 if (diff > 33) {
3806 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3807 BID_RETURN (res);
3810 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3811 // adjust the y significand upwards
3812 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
3837 // if postitive, return whichever significand is larger (converse if negative)
3838 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
3839 && (sig_n_prime192.w[0] == sig_x.w[0])) {
3840 res = 0;
3841 BID_RETURN (res);
3842 } // if equal, return 0
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);
3853 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
3854 bid128_signaling_not_greater,
3855 x, y)
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;
3865 // NaN (CASE1)
3866 // if either number is NAN, the comparison is unordered,
3867 // rather than equal : return 0
3868 if (((x.w[1] & MASK_NAN) == MASK_NAN)
3869 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
3870 *pfpsf |= INVALID_EXCEPTION;
3872 res = 1;
3873 BID_RETURN (res);
3876 // SIMPLE (CASE2)
3877 // if all the bits are the same, these numbers are equal (not Greater).
3878 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
3879 res = 1;
3880 BID_RETURN (res);
3882 // INFINITY (CASE3)
3883 if ((x.w[1] & MASK_INF) == MASK_INF) {
3884 // if x is neg infinity, there is no way it is greater than y, return 1
3885 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
3886 res = 1;
3887 BID_RETURN (res);
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);
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
3899 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3900 BID_RETURN (res);
3903 // CONVERT X
3904 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
3905 sig_x.w[0] = x.w[0];
3906 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
3908 // CHECK IF X IS CANONICAL
3909 // 9999999999999999999999999999999999(decimal) =
3910 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3911 // [0, 10^34) is the 754r supported canonical range.
3912 // If the value exceeds that, it is interpreted as 0.
3913 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
3914 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
3915 && (sig_x.w[0] > 0x378d8e63ffffffffull))
3916 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3917 non_canon_x = 1;
3918 else
3919 non_canon_x = 0;
3921 // CONVERT Y
3922 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
3923 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
3924 sig_y.w[0] = y.w[0];
3926 // CHECK IF Y IS CANONICAL
3927 // 9999999999999999999999999999999999(decimal) =
3928 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3929 // [0, 10^34) is the 754r supported canonical range.
3930 // If the value exceeds that, it is interpreted as 0.
3931 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
3932 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
3933 && (sig_y.w[0] > 0x378d8e63ffffffffull))
3934 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3935 non_canon_y = 1;
3936 else
3937 non_canon_y = 0;
3939 // ZERO (CASE4)
3940 // some properties:
3941 // (+ZERO == -ZERO) => therefore ignore the sign
3942 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
3943 // ignore the exponent field
3944 // (Any non-canonical # is considered 0)
3945 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
3946 x_is_zero = 1;
3948 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
3949 y_is_zero = 1;
3951 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
3952 if (x_is_zero && y_is_zero) {
3953 res = 1;
3954 BID_RETURN (res);
3956 // is x is zero, it is greater if Y is negative
3957 else if (x_is_zero) {
3958 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3959 BID_RETURN (res);
3961 // is y is zero, X is greater if it is positive
3962 else if (y_is_zero) {
3963 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3964 BID_RETURN (res);
3966 // OPPOSITE SIGN (CASE5)
3967 // now, if the sign bits differ, x is greater if y is negative
3968 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
3969 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3970 BID_RETURN (res);
3972 // REDUNDANT REPRESENTATIONS (CASE6)
3973 // if exponents are the same, then we have a simple comparison
3974 // of the significands
3975 if (exp_y == exp_x) {
3976 res = (((sig_x.w[1] > sig_y.w[1])
3977 || (sig_x.w[1] == sig_y.w[1]
3978 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
3979 MASK_SIGN));
3980 BID_RETURN (res);
3982 // if both components are either bigger or smaller,
3983 // it is clear what needs to be done
3984 if ((sig_x.w[1] > sig_y.w[1]
3985 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
3986 && exp_x >= exp_y) {
3987 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3988 BID_RETURN (res);
3990 if ((sig_x.w[1] < sig_y.w[1]
3991 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
3992 && exp_x <= exp_y) {
3993 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3994 BID_RETURN (res);
3997 diff = exp_x - exp_y;
3999 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
4000 if (diff > 0) { // to simplify the loop below,
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
4008 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
4009 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
4029 //else { //128 by 64 bit multiply -> 192 bits
4030 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
4049 diff = exp_y - exp_x;
4051 // if exp_x is 33 less than exp_y, no need for compensation
4052 if (diff > 33) {
4053 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
4054 BID_RETURN (res);
4057 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
4058 // adjust the y significand upwards
4059 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
4083 // if postitive, return whichever significand is larger
4084 // (converse if negative)
4085 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
4086 && (sig_n_prime192.w[0] == sig_x.w[0])) {
4087 res = 1;
4088 BID_RETURN (res);
4089 } // if equal, return 0
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);
4100 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
4101 bid128_signaling_not_less, x,
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;
4112 // NaN (CASE1)
4113 // if either number is NAN, the comparison is unordered,
4114 // rather than equal : return 1
4115 if (((x.w[1] & MASK_NAN) == MASK_NAN)
4116 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
4117 *pfpsf |= INVALID_EXCEPTION;
4119 res = 1;
4120 BID_RETURN (res);
4123 // SIMPLE (CASE2)
4124 // if all the bits are the same, these numbers are equal (not Greater).
4125 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
4126 res = 1;
4127 BID_RETURN (res);
4129 // INFINITY (CASE3)
4130 if ((x.w[1] & MASK_INF) == MASK_INF) {
4131 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
4132 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
4133 // x is -inf, so it is less than y unless y is -inf
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
4141 res = 1;
4142 BID_RETURN (res);
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
4148 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
4149 BID_RETURN (res);
4152 // CONVERT X
4153 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
4154 sig_x.w[0] = x.w[0];
4155 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
4157 // CHECK IF X IS CANONICAL
4158 // 9999999999999999999999999999999999(decimal) =
4159 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
4160 // [0, 10^34) is the 754r supported canonical range.
4161 // If the value exceeds that, it is interpreted as 0.
4162 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
4163 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
4164 && (sig_x.w[0] > 0x378d8e63ffffffffull))
4165 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
4166 non_canon_x = 1;
4167 else
4168 non_canon_x = 0;
4170 // CONVERT Y
4171 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
4172 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
4173 sig_y.w[0] = y.w[0];
4175 // CHECK IF Y IS CANONICAL
4176 // 9999999999999999999999999999999999(decimal) =
4177 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
4178 // [0, 10^34) is the 754r supported canonical range.
4179 // If the value exceeds that, it is interpreted as 0.
4180 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
4181 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
4182 && (sig_y.w[0] > 0x378d8e63ffffffffull))
4183 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
4184 non_canon_y = 1;
4185 else
4186 non_canon_y = 0;
4188 // ZERO (CASE4)
4189 // some properties:
4190 // (+ZERO == -ZERO) => therefore ignore the sign
4191 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
4192 // ignore the exponent field
4193 // (Any non-canonical # is considered 0)
4194 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
4195 x_is_zero = 1;
4197 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
4198 y_is_zero = 1;
4200 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
4201 if (x_is_zero && y_is_zero) {
4202 res = 1;
4203 BID_RETURN (res);
4205 // is x is zero, it is greater if Y is negative
4206 else if (x_is_zero) {
4207 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
4208 BID_RETURN (res);
4210 // is y is zero, X is greater if it is positive
4211 else if (y_is_zero) {
4212 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
4213 BID_RETURN (res);
4215 // OPPOSITE SIGN (CASE5)
4216 // now, if the sign bits differ, x is greater if y is negative
4217 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
4218 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
4219 BID_RETURN (res);
4221 // REDUNDANT REPRESENTATIONS (CASE6)
4223 // if exponents are the same, then we have a simple comparison
4224 // of the significands
4225 if (exp_y == exp_x) {
4226 res = (((sig_x.w[1] > sig_y.w[1])
4227 || (sig_x.w[1] == sig_y.w[1]
4228 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
4229 MASK_SIGN));
4230 BID_RETURN (res);
4232 // if both components are either bigger or smaller,
4233 // it is clear what needs to be done
4234 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
4235 && exp_x > exp_y) {
4236 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
4237 BID_RETURN (res);
4239 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
4240 && exp_x < exp_y) {
4241 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
4242 BID_RETURN (res);
4245 diff = exp_x - exp_y;
4247 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
4248 if (diff > 0) { // to simplify the loop below,
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
4256 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
4257 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
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
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);
4277 //else { //128 by 64 bit multiply -> 192 bits
4278 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
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
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);
4297 diff = exp_y - exp_x;
4299 // if exp_x is 33 less than exp_y, no need for compensation
4300 if (diff > 33) {
4301 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
4302 BID_RETURN (res);
4305 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
4306 // adjust the y significand upwards
4307 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
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
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);
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);
4332 // if postitive, return whichever significand is larger (converse if negative)
4333 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
4334 && (sig_n_prime192.w[0] == sig_x.w[0])) {
4335 res = 1;
4336 BID_RETURN (res);
4337 } // if equal, return 1
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);