Merge -r 127928:132243 from trunk
[official-gcc.git] / libgcc / config / libbid / bid128_compare.c
blobfd78019f62c3c5f817b8f57593e73a11c76cf020
1 /* Copyright (C) 2007 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 2, or (at your option) any later
8 version.
10 In addition to the permissions in the GNU General Public License, the
11 Free Software Foundation gives you unlimited permission to link the
12 compiled version of this file into combinations with other programs,
13 and to distribute those combinations without any restriction coming
14 from the use of this file. (The General Public License restrictions
15 do apply in other respects; for example, they cover modification of
16 the file, and distribution when not linked into a combine
17 executable.)
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING. If not, write to the Free
26 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
27 02110-1301, USA. */
29 #include "bid_internal.h"
31 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_equal, x, y)
33 int res;
34 int exp_x, exp_y, exp_t;
35 UINT128 sig_x, sig_y, sig_t;
36 UINT192 sig_n_prime192;
37 UINT256 sig_n_prime256;
38 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
40 // NaN (CASE1)
41 // if either number is NAN, the comparison is unordered,
42 // rather than equal : return 0
43 if (((x.w[1] & MASK_NAN) == MASK_NAN)
44 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
45 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
46 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
47 *pfpsf |= INVALID_EXCEPTION;
50 res = 0;
51 BID_RETURN (res);
54 // SIMPLE (CASE2)
55 // if all the bits are the same, these numbers are equivalent.
56 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
57 res = 1;
58 BID_RETURN (res);
60 // INFINITY (CASE3)
61 if ((x.w[1] & MASK_INF) == MASK_INF) {
62 if ((y.w[1] & MASK_INF) == MASK_INF) {
63 res = (((x.w[1] ^ y.w[1]) & MASK_SIGN) != MASK_SIGN);
64 BID_RETURN (res);
65 } else {
66 res = 0;
67 BID_RETURN (res);
70 if ((y.w[1] & MASK_INF) == MASK_INF) {
71 res = 0;
72 BID_RETURN (res);
74 // CONVERT X
75 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
76 sig_x.w[0] = x.w[0];
77 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
79 // CHECK IF X IS CANONICAL
80 // 9999999999999999999999999999999999(decimal) =
81 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
82 // [0, 10^34) is the 754r supported canonical range.
83 // If the value exceeds that, it is interpreted as 0.
84 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
85 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
86 && (sig_x.w[0] > 0x378d8e63ffffffffull))
87 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
88 non_canon_x = 1;
89 else
90 non_canon_x = 0;
92 // CONVERT Y
93 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
94 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
95 sig_y.w[0] = y.w[0];
97 // CHECK IF Y IS CANONICAL
98 // 9999999999999999999999999999999999(decimal) =
99 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
100 // [0, 10^34) is the 754r supported canonical range.
101 // If the value exceeds that, it is interpreted as 0.
102 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
103 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
104 && (sig_y.w[0] > 0x378d8e63ffffffffull))
105 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
106 non_canon_y = 1;
107 else
108 non_canon_y = 0;
110 // some properties:
111 // (+ZERO == -ZERO) => therefore ignore the sign
112 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
113 // ignore the exponent field
114 // (Any non-canonical # is considered 0)
115 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
116 x_is_zero = 1;
118 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
119 y_is_zero = 1;
122 if (x_is_zero && y_is_zero) {
123 res = 1;
124 BID_RETURN (res);
125 } else if ((x_is_zero && !y_is_zero) || (!x_is_zero && y_is_zero)) {
126 res = 0;
127 BID_RETURN (res);
129 // OPPOSITE SIGN (CASE5)
130 // now, if the sign bits differ => not equal : return 0
131 if ((x.w[1] ^ y.w[1]) & MASK_SIGN) {
132 res = 0;
133 BID_RETURN (res);
135 // REDUNDANT REPRESENTATIONS (CASE6)
136 if (exp_x > exp_y) { // to simplify the loop below,
137 SWAP (exp_x, exp_y, exp_t); // put the larger exp in y,
138 SWAP (sig_x.w[1], sig_y.w[1], sig_t.w[1]); // and the smaller exp in x
139 SWAP (sig_x.w[0], sig_y.w[0], sig_t.w[0]); // and the smaller exp in x
143 if (exp_y - exp_x > 33) {
144 res = 0;
145 BID_RETURN (res);
146 } // difference cannot be greater than 10^33
148 if (exp_y - exp_x > 19) {
149 // recalculate y's significand upwards
150 __mul_128x128_to_256 (sig_n_prime256, sig_y,
151 ten2k128[exp_y - exp_x - 20]);
153 res = ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
154 && (sig_n_prime256.w[1] == sig_x.w[1])
155 && (sig_n_prime256.w[0] == sig_x.w[0]));
156 BID_RETURN (res);
160 //else{
161 // recalculate y's significand upwards
162 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y);
164 res = ((sig_n_prime192.w[2] == 0)
165 && (sig_n_prime192.w[1] == sig_x.w[1])
166 && (sig_n_prime192.w[0] == sig_x.w[0]));
167 BID_RETURN (res);
171 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_greater, x,
174 int res;
175 int exp_x, exp_y;
176 int diff;
177 UINT128 sig_x, sig_y;
178 UINT192 sig_n_prime192;
179 UINT256 sig_n_prime256;
180 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
182 // NaN (CASE1)
183 // if either number is NAN, the comparison is unordered, rather than
184 // equal : return 0
185 if (((x.w[1] & MASK_NAN) == MASK_NAN)
186 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
187 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
188 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
189 *pfpsf |= INVALID_EXCEPTION;
192 res = 0;
193 BID_RETURN (res);
196 // SIMPLE (CASE2)
197 // if all the bits are the same, these numbers are equal (not Greater).
198 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
199 res = 0;
200 BID_RETURN (res);
202 // INFINITY (CASE3)
203 if ((x.w[1] & MASK_INF) == MASK_INF) {
204 // if x is neg infinity, there is no way it is greater than y, return 0
205 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
206 res = 0;
207 BID_RETURN (res);
209 // x is pos infinity, it is greater, unless y is positive infinity =>
210 // return y!=pos_infinity
211 else {
212 res = (((y.w[1] & MASK_INF) != MASK_INF)
213 || ((y.w[1] & MASK_SIGN) == MASK_SIGN));
214 BID_RETURN (res);
216 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
217 // x is finite, so if y is positive infinity, then x is less, return 0
218 // if y is negative infinity, then x is greater, return 1
220 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
221 BID_RETURN (res);
224 // CONVERT X
225 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
226 sig_x.w[0] = x.w[0];
227 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
229 // CHECK IF X IS CANONICAL
230 // 9999999999999999999999999999999999(decimal) =
231 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
232 // [0, 10^34) is the 754r supported canonical range.
233 // If the value exceeds that, it is interpreted as 0.
234 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
235 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
236 && (sig_x.w[0] > 0x378d8e63ffffffffull))
237 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
238 non_canon_x = 1;
239 else
240 non_canon_x = 0;
242 // CONVERT Y
243 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
244 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
245 sig_y.w[0] = y.w[0];
247 // CHECK IF Y IS CANONICAL
248 // 9999999999999999999999999999999999(decimal) =
249 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
250 // [0, 10^34) is the 754r supported canonical range.
251 // If the value exceeds that, it is interpreted as 0.
252 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
253 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
254 && (sig_y.w[0] > 0x378d8e63ffffffffull))
255 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
256 non_canon_y = 1;
257 else
258 non_canon_y = 0;
260 // ZERO (CASE4)
261 // some properties:
262 // (+ZERO == -ZERO) => therefore ignore the sign
263 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
264 // ignore the exponent field
265 // (Any non-canonical # is considered 0)
266 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
267 x_is_zero = 1;
269 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
270 y_is_zero = 1;
272 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
273 if (x_is_zero && y_is_zero) {
274 res = 0;
275 BID_RETURN (res);
277 // is x is zero, it is greater if Y is negative
278 else if (x_is_zero) {
279 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
280 BID_RETURN (res);
282 // is y is zero, X is greater if it is positive
283 else if (y_is_zero) {
284 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
285 BID_RETURN (res);
287 // OPPOSITE SIGN (CASE5)
288 // now, if the sign bits differ, x is greater if y is negative
289 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
290 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
291 BID_RETURN (res);
293 // REDUNDANT REPRESENTATIONS (CASE6)
294 // if exponents are the same, then we have a simple comparison
295 // of the significands
296 if (exp_y == exp_x) {
297 res = (((sig_x.w[1] > sig_y.w[1])
298 || (sig_x.w[1] == sig_y.w[1]
299 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
300 MASK_SIGN));
301 BID_RETURN (res);
303 // if both components are either bigger or smaller,
304 // it is clear what needs to be done
305 if ((sig_x.w[1] > sig_y.w[1]
306 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
307 && exp_x >= exp_y) {
309 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
310 BID_RETURN (res);
313 if ((sig_x.w[1] < sig_y.w[1]
314 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
315 && exp_x <= exp_y) {
317 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
318 BID_RETURN (res);
322 diff = exp_x - exp_y;
324 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
325 if (diff > 0) { // to simplify the loop below,
327 // if exp_x is 33 greater than exp_y, no need for compensation
328 if (diff > 33) {
329 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
330 BID_RETURN (res);
331 } // difference cannot be greater than 10^33
333 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
334 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
336 // if postitive, return whichever significand is larger
337 // (converse if negative)
338 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
339 && sig_n_prime256.w[1] == sig_y.w[1]
340 && (sig_n_prime256.w[0] == sig_y.w[0])) {
341 res = 0;
342 BID_RETURN (res);
343 } // if equal, return 0
345 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
346 || (sig_n_prime256.w[1] > sig_y.w[1])
347 || (sig_n_prime256.w[1] == sig_y.w[1]
348 && sig_n_prime256.w[0] >
349 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
350 BID_RETURN (res);
353 //else { //128 by 64 bit multiply -> 192 bits
354 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
356 // if postitive, return whichever significand is larger
357 // (converse if negative)
358 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
359 && (sig_n_prime192.w[0] == sig_y.w[0])) {
360 res = 0;
361 BID_RETURN (res);
362 } // if equal, return 0
364 res = (((sig_n_prime192.w[2] > 0) ||
365 (sig_n_prime192.w[1] > sig_y.w[1]) ||
366 (sig_n_prime192.w[1] == sig_y.w[1] &&
367 sig_n_prime192.w[0] > sig_y.w[0])) ^
368 ((y.w[1] & MASK_SIGN) == MASK_SIGN));
369 BID_RETURN (res);
373 diff = exp_y - exp_x;
375 // if exp_x is 33 less than exp_y, no need for compensation
376 if (diff > 33) {
377 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
378 BID_RETURN (res);
381 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
382 // adjust the y significand upwards
383 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
385 // if postitive, return whichever significand is larger
386 // (converse if negative)
387 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
388 && sig_n_prime256.w[1] == sig_x.w[1]
389 && (sig_n_prime256.w[0] == sig_x.w[0])) {
390 res = 0;
391 BID_RETURN (res);
392 } // if equal, return 0
394 res = ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0 ||
395 (sig_n_prime256.w[1] > sig_x.w[1] ||
396 (sig_n_prime256.w[1] == sig_x.w[1] &&
397 sig_n_prime256.w[0] > sig_x.w[0]))) ^
398 ((x.w[1] & MASK_SIGN) != MASK_SIGN));
399 BID_RETURN (res);
402 //else { //128 by 64 bit multiply -> 192 bits
403 // adjust the y significand upwards
404 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
406 // if postitive, return whichever significand is larger
407 // (converse if negative)
408 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
409 && (sig_n_prime192.w[0] == sig_x.w[0])) {
410 res = 0;
411 BID_RETURN (res);
412 } // if equal, return 0
414 res = (sig_n_prime192.w[2] != 0
415 || (sig_n_prime192.w[1] > sig_x.w[1]
416 || (sig_n_prime192.w[1] == sig_x.w[1]
417 && sig_n_prime192.w[0] >
418 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN);
419 BID_RETURN (res);
423 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
424 bid128_quiet_greater_equal, x,
427 int res;
428 int exp_x, exp_y;
429 int diff;
430 UINT128 sig_x, sig_y;
431 UINT192 sig_n_prime192;
432 UINT256 sig_n_prime256;
433 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
435 // NaN (CASE1)
436 // if either number is NAN, the comparison is unordered,
437 // rather than equal : return 1
438 if (((x.w[1] & MASK_NAN) == MASK_NAN)
439 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
440 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
441 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
442 *pfpsf |= INVALID_EXCEPTION;
445 res = 0;
446 BID_RETURN (res);
449 // SIMPLE (CASE2)
450 // if all the bits are the same, these numbers are equal (not Greater).
451 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
452 res = 1;
453 BID_RETURN (res);
455 // INFINITY (CASE3)
456 if ((x.w[1] & MASK_INF) == MASK_INF) {
457 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
458 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
459 // x is -inf, so it is less than y unless y is -inf
461 res = (((y.w[1] & MASK_INF) == MASK_INF)
462 && (y.w[1] & MASK_SIGN) == MASK_SIGN);
463 BID_RETURN (res);
464 } else
465 // x is pos_inf, no way for it to be less than y
467 res = 1;
468 BID_RETURN (res);
470 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
471 // x is finite, so if y is positive infinity, then x is less, return 0
472 // if y is negative infinity, then x is greater, return 1
474 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
475 BID_RETURN (res);
478 // CONVERT X
479 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
480 sig_x.w[0] = x.w[0];
481 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
483 // CHECK IF X IS CANONICAL
484 // 9999999999999999999999999999999999(decimal) =
485 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
486 // [0, 10^34) is the 754r supported canonical range.
487 // If the value exceeds that, it is interpreted as 0.
488 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
489 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
490 && (sig_x.w[0] > 0x378d8e63ffffffffull))
491 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
492 non_canon_x = 1;
493 else
494 non_canon_x = 0;
496 // CONVERT Y
497 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
498 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
499 sig_y.w[0] = y.w[0];
501 // CHECK IF Y IS CANONICAL
502 // 9999999999999999999999999999999999(decimal) =
503 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
504 // [0, 10^34) is the 754r supported canonical range.
505 // If the value exceeds that, it is interpreted as 0.
506 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
507 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
508 && (sig_y.w[0] > 0x378d8e63ffffffffull))
509 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
510 non_canon_y = 1;
511 else
512 non_canon_y = 0;
514 // ZERO (CASE4)
515 // some properties:
516 // (+ZERO == -ZERO) => therefore ignore the sign
517 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
518 // ignore the exponent field
519 // (Any non-canonical # is considered 0)
520 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
521 x_is_zero = 1;
523 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
524 y_is_zero = 1;
526 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
527 if (x_is_zero && y_is_zero) {
528 res = 1;
529 BID_RETURN (res);
531 // is x is zero, it is greater if Y is negative
532 else if (x_is_zero) {
533 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
534 BID_RETURN (res);
536 // is y is zero, X is greater if it is positive
537 else if (y_is_zero) {
538 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
539 BID_RETURN (res);
541 // OPPOSITE SIGN (CASE5)
542 // now, if the sign bits differ, x is greater if y is negative
543 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
544 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
545 BID_RETURN (res);
547 // REDUNDANT REPRESENTATIONS (CASE6)
548 // if exponents are the same, then we have a simple comparison of the
549 // significands
550 if (exp_y == exp_x) {
551 res = (((sig_x.w[1] > sig_y.w[1])
552 || (sig_x.w[1] == sig_y.w[1]
553 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
554 MASK_SIGN));
555 BID_RETURN (res);
557 // if both components are either bigger or smaller,
558 // it is clear what needs to be done
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);
564 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
565 && exp_x < exp_y) {
566 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
567 BID_RETURN (res);
570 diff = exp_x - exp_y;
572 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
573 if (diff > 0) { // to simplify the loop below,
575 // if exp_x is 33 greater than exp_y, no need for compensation
576 if (diff > 33) {
577 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
578 BID_RETURN (res);
579 } // difference cannot be greater than 10^33
581 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
582 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
585 // if postitive, return whichever significand is larger
586 // (converse if negative)
587 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
588 && sig_n_prime256.w[1] == sig_y.w[1]
589 && (sig_n_prime256.w[0] == sig_y.w[0])) {
590 res = 1;
591 BID_RETURN (res);
592 } // if equal, return 1
594 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
595 || (sig_n_prime256.w[1] > sig_y.w[1])
596 || (sig_n_prime256.w[1] == sig_y.w[1]
597 && sig_n_prime256.w[0] >
598 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
599 BID_RETURN (res);
602 //else { //128 by 64 bit multiply -> 192 bits
603 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
605 // if postitive, return whichever significand is larger
606 // (converse if negative)
607 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
608 && (sig_n_prime192.w[0] == sig_y.w[0])) {
609 res = 1;
610 BID_RETURN (res);
611 } // if equal, return 1
613 res = (((sig_n_prime192.w[2] > 0)
614 || (sig_n_prime192.w[1] > sig_y.w[1])
615 || (sig_n_prime192.w[1] == sig_y.w[1]
616 && sig_n_prime192.w[0] >
617 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
618 BID_RETURN (res);
622 diff = exp_y - exp_x;
624 // if exp_x is 33 less than exp_y, no need for compensation
625 if (diff > 33) {
626 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
627 BID_RETURN (res);
630 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
631 // adjust the y significand upwards
632 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
635 // if postitive, return whichever significand is larger
636 // (converse if negative)
637 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
638 && sig_n_prime256.w[1] == sig_x.w[1]
639 && (sig_n_prime256.w[0] == sig_x.w[0])) {
640 res = 1;
641 BID_RETURN (res);
642 } // if equal, return 1
644 res = ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
645 && (sig_n_prime256.w[1] < sig_x.w[1]
646 || (sig_n_prime256.w[1] == sig_x.w[1]
647 && sig_n_prime256.w[0] <
648 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
649 MASK_SIGN));
650 BID_RETURN (res);
653 //else { //128 by 64 bit multiply -> 192 bits
654 // adjust the y significand upwards
655 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
657 // if postitive, return whichever significand is larger
658 // (converse if negative)
659 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
660 && (sig_n_prime192.w[0] == sig_x.w[0])) {
661 res = 1;
662 BID_RETURN (res);
663 } // if equal, return 1
665 res = (sig_n_prime192.w[2] == 0
666 && (sig_n_prime192.w[1] < sig_x.w[1]
667 || (sig_n_prime192.w[1] == sig_x.w[1]
668 && sig_n_prime192.w[0] <
669 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
670 BID_RETURN (res);
674 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
675 bid128_quiet_greater_unordered,
676 x, y)
678 int res;
679 int exp_x, exp_y;
680 int diff;
681 UINT128 sig_x, sig_y;
682 UINT192 sig_n_prime192;
683 UINT256 sig_n_prime256;
684 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
686 // NaN (CASE1)
687 // if either number is NAN, the comparison is unordered,
688 // rather than
689 // equal : return 1
690 if (((x.w[1] & MASK_NAN) == MASK_NAN)
691 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
692 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
693 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
694 *pfpsf |= INVALID_EXCEPTION;
697 res = 1;
698 BID_RETURN (res);
701 // SIMPLE (CASE2)
702 // if all the bits are the same, these numbers are equal (not Greater).
703 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
704 res = 0;
705 BID_RETURN (res);
707 // INFINITY (CASE3)
708 if ((x.w[1] & MASK_INF) == MASK_INF) {
709 // if x is neg infinity, there is no way it is greater than y, return 0
710 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
711 res = 0;
712 BID_RETURN (res);
714 // x is pos infinity, it is greater, unless y is positive infinity =>
715 // return y!=pos_infinity
716 else {
717 res = (((y.w[1] & MASK_INF) != MASK_INF)
718 || ((y.w[1] & MASK_SIGN) == MASK_SIGN));
719 BID_RETURN (res);
721 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
722 // x is finite, so if y is positive infinity, then x is less, return 0
723 // if y is negative infinity, then x is greater, return 1
725 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
726 BID_RETURN (res);
729 // CONVERT X
730 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
731 sig_x.w[0] = x.w[0];
732 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
734 // CHECK IF X IS CANONICAL
735 // 9999999999999999999999999999999999(decimal) =
736 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
737 // [0, 10^34) is the 754r supported canonical range.
738 // If the value exceeds that, it is interpreted as 0.
739 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
740 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
741 && (sig_x.w[0] > 0x378d8e63ffffffffull))
742 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
743 non_canon_x = 1;
744 else
745 non_canon_x = 0;
747 // CONVERT Y
748 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
749 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
750 sig_y.w[0] = y.w[0];
752 // CHECK IF Y IS CANONICAL
753 // 9999999999999999999999999999999999(decimal) =
754 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
755 // [0, 10^34) is the 754r supported canonical range.
756 // If the value exceeds that, it is interpreted as 0.
757 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
758 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
759 && (sig_y.w[0] > 0x378d8e63ffffffffull))
760 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
761 non_canon_y = 1;
762 else
763 non_canon_y = 0;
765 // ZERO (CASE4)
766 // some properties:
767 // (+ZERO == -ZERO) => therefore ignore the sign
768 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
769 // ignore the exponent field
770 // (Any non-canonical # is considered 0)
771 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
772 x_is_zero = 1;
774 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
775 y_is_zero = 1;
777 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
778 if (x_is_zero && y_is_zero) {
779 res = 0;
780 BID_RETURN (res);
782 // is x is zero, it is greater if Y is negative
783 else if (x_is_zero) {
784 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
785 BID_RETURN (res);
787 // is y is zero, X is greater if it is positive
788 else if (y_is_zero) {
789 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
790 BID_RETURN (res);
792 // OPPOSITE SIGN (CASE5)
793 // now, if the sign bits differ, x is greater if y is negative
794 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
795 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
796 BID_RETURN (res);
798 // REDUNDANT REPRESENTATIONS (CASE6)
799 // if exponents are the same, then we have a simple comparison of the
800 // significands
801 if (exp_y == exp_x) {
802 res = (((sig_x.w[1] > sig_y.w[1])
803 || (sig_x.w[1] == sig_y.w[1]
804 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
805 MASK_SIGN));
806 BID_RETURN (res);
808 // if both components are either bigger or smaller,
809 // it is clear what needs to be done
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);
815 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
816 && exp_x < exp_y) {
817 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
818 BID_RETURN (res);
821 diff = exp_x - exp_y;
823 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
824 if (diff > 0) { // to simplify the loop below,
826 // if exp_x is 33 greater than exp_y, no need for compensation
827 if (diff > 33) {
828 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
829 BID_RETURN (res);
830 } // difference cannot be greater than 10^33
832 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
833 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
836 // if postitive, return whichever significand is larger
837 // (converse if negative)
838 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
839 && sig_n_prime256.w[1] == sig_y.w[1]
840 && (sig_n_prime256.w[0] == sig_y.w[0])) {
841 res = 0;
842 BID_RETURN (res);
843 } // if equal, return 0
845 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
846 || (sig_n_prime256.w[1] > sig_y.w[1])
847 || (sig_n_prime256.w[1] == sig_y.w[1]
848 && sig_n_prime256.w[0] >
849 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
850 BID_RETURN (res);
853 //else { //128 by 64 bit multiply -> 192 bits
854 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
856 // if postitive, return whichever significand is larger
857 // (converse if negative)
858 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
859 && (sig_n_prime192.w[0] == sig_y.w[0])) {
860 res = 0;
861 BID_RETURN (res);
862 } // if equal, return 0
864 res = (((sig_n_prime192.w[2] > 0)
865 || (sig_n_prime192.w[1] > sig_y.w[1])
866 || (sig_n_prime192.w[1] == sig_y.w[1]
867 && sig_n_prime192.w[0] >
868 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
869 BID_RETURN (res);
873 diff = exp_y - exp_x;
875 // if exp_x is 33 less than exp_y, no need for compensation
876 if (diff > 33) {
877 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
878 BID_RETURN (res);
881 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
882 // adjust the y significand upwards
883 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
886 // if postitive, return whichever significand is larger
887 // (converse if negative)
888 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
889 && sig_n_prime256.w[1] == sig_x.w[1]
890 && (sig_n_prime256.w[0] == sig_x.w[0])) {
891 res = 0;
892 BID_RETURN (res);
893 } // if equal, return 0
895 res = ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
896 && (sig_n_prime256.w[1] < sig_x.w[1]
897 || (sig_n_prime256.w[1] == sig_x.w[1]
898 && sig_n_prime256.w[0] <
899 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
900 MASK_SIGN));
901 BID_RETURN (res);
904 //else { //128 by 64 bit multiply -> 192 bits
905 // adjust the y significand upwards
906 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
908 // if postitive, return whichever significand is larger
909 // (converse if negative)
910 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
911 && (sig_n_prime192.w[0] == sig_x.w[0])) {
912 res = 0;
913 BID_RETURN (res);
914 } // if equal, return 0
916 res = (sig_n_prime192.w[2] == 0
917 && (sig_n_prime192.w[1] < sig_x.w[1]
918 || (sig_n_prime192.w[1] == sig_x.w[1]
919 && sig_n_prime192.w[0] <
920 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
921 BID_RETURN (res);
925 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_less, x, y)
927 int res;
928 int exp_x, exp_y;
929 int diff;
930 UINT128 sig_x, sig_y;
931 UINT192 sig_n_prime192;
932 UINT256 sig_n_prime256;
933 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
935 // NaN (CASE1)
936 // if either number is NAN, the comparison is unordered,
937 // rather than equal : return 0
938 if (((x.w[1] & MASK_NAN) == MASK_NAN)
939 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
940 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
941 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
942 *pfpsf |= INVALID_EXCEPTION;
945 res = 0;
946 BID_RETURN (res);
949 // SIMPLE (CASE2)
950 // if all the bits are the same, these numbers are equal.
951 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
952 res = 0;
953 BID_RETURN (res);
955 // INFINITY (CASE3)
956 if ((x.w[1] & MASK_INF) == MASK_INF) {
957 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
958 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
959 // x is -inf, so it is less than y unless y is -inf
961 res = (((y.w[1] & MASK_INF) != MASK_INF)
962 || (y.w[1] & MASK_SIGN) != MASK_SIGN);
963 BID_RETURN (res);
964 } else
965 // x is pos_inf, no way for it to be less than y
967 res = 0;
968 BID_RETURN (res);
970 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
971 // x is finite, so if y is positive infinity, then x is less, return 0
972 // if y is negative infinity, then x is greater, return 1
974 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
975 BID_RETURN (res);
978 // CONVERT X
979 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
980 sig_x.w[0] = x.w[0];
981 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
983 // CHECK IF X IS CANONICAL
984 // 9999999999999999999999999999999999(decimal) =
985 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
986 // [0, 10^34) is the 754r supported canonical range.
987 // If the value exceeds that, it is interpreted as 0.
988 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
989 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
990 && (sig_x.w[0] > 0x378d8e63ffffffffull))
991 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
992 non_canon_x = 1;
993 else
994 non_canon_x = 0;
996 // CONVERT Y
997 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
998 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
999 sig_y.w[0] = y.w[0];
1001 // CHECK IF Y IS CANONICAL
1002 // 9999999999999999999999999999999999(decimal) =
1003 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1004 // [0, 10^34) is the 754r supported canonical range.
1005 // If the value exceeds that, it is interpreted as 0.
1006 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1007 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1008 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1009 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1010 non_canon_y = 1;
1011 else
1012 non_canon_y = 0;
1014 // ZERO (CASE4)
1015 // some properties:
1016 // (+ZERO == -ZERO) => therefore ignore the sign
1017 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1018 // ignore the exponent field
1019 // (Any non-canonical # is considered 0)
1020 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1021 x_is_zero = 1;
1023 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1024 y_is_zero = 1;
1026 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
1027 if (x_is_zero && y_is_zero) {
1028 res = 0;
1029 BID_RETURN (res);
1031 // is x is zero, it is greater if Y is negative
1032 else if (x_is_zero) {
1033 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1034 BID_RETURN (res);
1036 // is y is zero, X is greater if it is positive
1037 else if (y_is_zero) {
1038 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1039 BID_RETURN (res);
1041 // OPPOSITE SIGN (CASE5)
1042 // now, if the sign bits differ, x is greater if y is negative
1043 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
1044 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1045 BID_RETURN (res);
1047 // REDUNDANT REPRESENTATIONS (CASE6)
1048 // if exponents are the same, then we have a simple comparison of the
1049 // significands
1050 if (exp_y == exp_x) {
1051 res = (((sig_x.w[1] > sig_y.w[1])
1052 || (sig_x.w[1] == sig_y.w[1]
1053 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
1054 MASK_SIGN));
1055 BID_RETURN (res);
1057 // if both components are either bigger or smaller,
1058 // it is clear what needs to be done
1059 if ((sig_x.w[1] > sig_y.w[1]
1060 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1061 && exp_x >= exp_y) {
1062 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1063 BID_RETURN (res);
1065 if ((sig_x.w[1] < sig_y.w[1]
1066 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1067 && exp_x <= exp_y) {
1068 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1069 BID_RETURN (res);
1072 diff = exp_x - exp_y;
1074 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1075 if (diff > 0) { // to simplify the loop below,
1077 // if exp_x is 33 greater than exp_y, no need for compensation
1078 if (diff > 33) {
1079 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1080 BID_RETURN (res);
1081 } // difference cannot be greater than 10^33
1083 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1084 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
1087 // if postitive, return whichever significand is larger
1088 // (converse if negative)
1089 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1090 && sig_n_prime256.w[1] == sig_y.w[1]
1091 && (sig_n_prime256.w[0] == sig_y.w[0])) {
1092 res = 0;
1093 BID_RETURN (res);
1094 } // if equal, return 0
1096 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
1097 || (sig_n_prime256.w[1] > sig_y.w[1])
1098 || (sig_n_prime256.w[1] == sig_y.w[1]
1099 && sig_n_prime256.w[0] >
1100 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
1101 BID_RETURN (res);
1104 //else { //128 by 64 bit multiply -> 192 bits
1105 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
1107 // if postitive, return whichever significand is larger
1108 // (converse if negative)
1109 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
1110 && (sig_n_prime192.w[0] == sig_y.w[0])) {
1111 res = 0;
1112 BID_RETURN (res);
1113 } // if equal, return 0
1115 res = (((sig_n_prime192.w[2] > 0)
1116 || (sig_n_prime192.w[1] > sig_y.w[1])
1117 || (sig_n_prime192.w[1] == sig_y.w[1]
1118 && sig_n_prime192.w[0] >
1119 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
1120 BID_RETURN (res);
1124 diff = exp_y - exp_x;
1126 // if exp_x is 33 less than exp_y, no need for compensation
1127 if (diff > 33) {
1128 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1129 BID_RETURN (res);
1132 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1133 // adjust the y significand upwards
1134 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
1136 // if postitive, return whichever significand is larger
1137 // (converse if negative)
1138 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1139 && sig_n_prime256.w[1] == sig_x.w[1]
1140 && (sig_n_prime256.w[0] == sig_x.w[0])) {
1141 res = 0;
1142 BID_RETURN (res);
1143 } // if equal, return 1
1145 res = ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
1146 || (sig_n_prime256.w[1] > sig_x.w[1]
1147 || (sig_n_prime256.w[1] == sig_x.w[1]
1148 && sig_n_prime256.w[0] >
1149 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
1150 MASK_SIGN));
1151 BID_RETURN (res);
1154 //else { //128 by 64 bit multiply -> 192 bits
1155 // adjust the y significand upwards
1156 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
1158 // if postitive, return whichever significand is larger
1159 // (converse if negative)
1160 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
1161 && (sig_n_prime192.w[0] == sig_x.w[0])) {
1162 res = 0;
1163 BID_RETURN (res);
1164 } // if equal, return 0
1166 res = (sig_n_prime192.w[2] != 0
1167 || (sig_n_prime192.w[1] > sig_x.w[1]
1168 || (sig_n_prime192.w[1] == sig_x.w[1]
1169 && sig_n_prime192.w[0] >
1170 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
1171 BID_RETURN (res);
1175 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_less_equal,
1176 x, y)
1178 int res;
1179 int exp_x, exp_y;
1180 int diff;
1181 UINT128 sig_x, sig_y;
1182 UINT192 sig_n_prime192;
1183 UINT256 sig_n_prime256;
1184 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
1186 // NaN (CASE1)
1187 // if either number is NAN, the comparison is unordered,
1188 // rather than equal : return 0
1189 if (((x.w[1] & MASK_NAN) == MASK_NAN)
1190 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
1191 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
1192 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
1193 *pfpsf |= INVALID_EXCEPTION;
1196 res = 0;
1197 BID_RETURN (res);
1200 // SIMPLE (CASE2)
1201 // if all the bits are the same, these numbers are equal (not Greater).
1202 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
1203 res = 1;
1204 BID_RETURN (res);
1206 // INFINITY (CASE3)
1207 if ((x.w[1] & MASK_INF) == MASK_INF) {
1208 // if x is neg infinity, there is no way it is greater than y, return 1
1209 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
1210 res = 1;
1211 BID_RETURN (res);
1213 // x is pos infinity, it is greater, unless y is positive infinity =>
1214 // return y!=pos_infinity
1215 else {
1216 res = (((y.w[1] & MASK_INF) == MASK_INF)
1217 && ((y.w[1] & MASK_SIGN) != MASK_SIGN));
1218 BID_RETURN (res);
1220 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
1221 // x is finite, so if y is positive infinity, then x is less, return 0
1222 // if y is negative infinity, then x is greater, return 1
1224 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1225 BID_RETURN (res);
1228 // CONVERT X
1229 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1230 sig_x.w[0] = x.w[0];
1231 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1233 // CHECK IF X IS CANONICAL
1234 // 9999999999999999999999999999999999(decimal) =
1235 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1236 // [0, 10^34) is the 754r supported canonical range.
1237 // If the value exceeds that, it is interpreted as 0.
1238 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
1239 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
1240 && (sig_x.w[0] > 0x378d8e63ffffffffull))
1241 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1242 non_canon_x = 1;
1243 else
1244 non_canon_x = 0;
1246 // CONVERT Y
1247 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1248 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1249 sig_y.w[0] = y.w[0];
1251 // CHECK IF Y IS CANONICAL
1252 // 9999999999999999999999999999999999(decimal) =
1253 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1254 // [0, 10^34) is the 754r supported canonical range.
1255 // If the value exceeds that, it is interpreted as 0.
1256 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1257 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1258 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1259 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1260 non_canon_y = 1;
1261 else
1262 non_canon_y = 0;
1264 // ZERO (CASE4)
1265 // some properties:
1266 // (+ZERO == -ZERO) => therefore ignore the sign
1267 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1268 // ignore the exponent field
1269 // (Any non-canonical # is considered 0)
1270 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1271 x_is_zero = 1;
1273 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1274 y_is_zero = 1;
1276 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
1277 if (x_is_zero && y_is_zero) {
1278 res = 1;
1279 BID_RETURN (res);
1281 // is x is zero, it is greater if Y is negative
1282 else if (x_is_zero) {
1283 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1284 BID_RETURN (res);
1286 // is y is zero, X is greater if it is positive
1287 else if (y_is_zero) {
1288 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1289 BID_RETURN (res);
1291 // OPPOSITE SIGN (CASE5)
1292 // now, if the sign bits differ, x is greater if y is negative
1293 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
1294 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1295 BID_RETURN (res);
1297 // REDUNDANT REPRESENTATIONS (CASE6)
1298 // if exponents are the same, then we have a simple comparison of the
1299 // significands
1300 if (exp_y == exp_x) {
1301 res = (((sig_x.w[1] > sig_y.w[1]) || (sig_x.w[1] == sig_y.w[1] &&
1302 sig_x.w[0] >=
1303 sig_y.w[0])) ^ ((x.
1304 w[1] &
1305 MASK_SIGN) !=
1306 MASK_SIGN));
1307 BID_RETURN (res);
1309 // if both components are either bigger or smaller,
1310 // it is clear what needs to be done
1311 if ((sig_x.w[1] > sig_y.w[1]
1312 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1313 && exp_x >= exp_y) {
1314 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1315 BID_RETURN (res);
1317 if ((sig_x.w[1] < sig_y.w[1]
1318 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1319 && exp_x <= exp_y) {
1320 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1321 BID_RETURN (res);
1324 diff = exp_x - exp_y;
1326 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1327 if (diff > 0) { // to simplify the loop below,
1329 // if exp_x is 33 greater than exp_y, no need for compensation
1330 if (diff > 33) {
1331 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1332 BID_RETURN (res);
1333 } // difference cannot be greater than 10^33
1335 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1336 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
1339 // if postitive, return whichever significand is larger
1340 // (converse if negative)
1341 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1342 && sig_n_prime256.w[1] == sig_y.w[1]
1343 && (sig_n_prime256.w[0] == sig_y.w[0])) {
1344 res = 1;
1345 BID_RETURN (res);
1346 } // if equal, return 0
1348 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
1349 || (sig_n_prime256.w[1] > sig_y.w[1])
1350 || (sig_n_prime256.w[1] == sig_y.w[1]
1351 && sig_n_prime256.w[0] >
1352 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
1353 BID_RETURN (res);
1356 //else { //128 by 64 bit multiply -> 192 bits
1357 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
1359 // if postitive, return whichever significand is larger
1360 // (converse if negative)
1361 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
1362 && (sig_n_prime192.w[0] == sig_y.w[0])) {
1363 res = 1;
1364 BID_RETURN (res);
1365 } // if equal, return 0
1367 res = (((sig_n_prime192.w[2] > 0)
1368 || (sig_n_prime192.w[1] > sig_y.w[1])
1369 || (sig_n_prime192.w[1] == sig_y.w[1]
1370 && sig_n_prime192.w[0] >
1371 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
1372 BID_RETURN (res);
1376 diff = exp_y - exp_x;
1378 // if exp_x is 33 less than exp_y, no need for compensation
1379 if (diff > 33) {
1380 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1381 BID_RETURN (res);
1384 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1385 // adjust the y significand upwards
1386 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
1389 // if postitive, return whichever significand is larger
1390 // (converse if negative)
1391 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1392 && sig_n_prime256.w[1] == sig_x.w[1]
1393 && (sig_n_prime256.w[0] == sig_x.w[0])) {
1394 res = 1;
1395 BID_RETURN (res);
1396 } // if equal, return 0
1398 res =
1399 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
1400 || (sig_n_prime256.w[1] > sig_x.w[1]
1401 || (sig_n_prime256.w[1] == sig_x.w[1]
1402 && sig_n_prime256.w[0] >
1403 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
1404 BID_RETURN (res);
1407 //else { //128 by 64 bit multiply -> 192 bits
1408 // adjust the y significand upwards
1409 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
1411 // if postitive, return whichever significand is larger
1412 // (converse if negative)
1413 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
1414 && (sig_n_prime192.w[0] == sig_x.w[0])) {
1415 res = 1;
1416 BID_RETURN (res);
1417 } // if equal, return 0
1419 res = (sig_n_prime192.w[2] != 0
1420 || (sig_n_prime192.w[1] > sig_x.w[1]
1421 || (sig_n_prime192.w[1] == sig_x.w[1]
1422 && sig_n_prime192.w[0] >
1423 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
1424 BID_RETURN (res);
1428 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
1429 bid128_quiet_less_unordered,
1430 x, y)
1432 int res;
1433 int exp_x, exp_y;
1434 int diff;
1435 UINT128 sig_x, sig_y;
1436 UINT192 sig_n_prime192;
1437 UINT256 sig_n_prime256;
1438 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
1440 // NaN (CASE1)
1441 // if either number is NAN, the comparison is unordered
1442 if (((x.w[1] & MASK_NAN) == MASK_NAN)
1443 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
1444 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
1445 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
1446 *pfpsf |= INVALID_EXCEPTION;
1449 res = 1;
1450 BID_RETURN (res);
1453 // SIMPLE (CASE2)
1454 // if all the bits are the same, these numbers are equal.
1455 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
1456 res = 0;
1457 BID_RETURN (res);
1459 // INFINITY (CASE3)
1460 if ((x.w[1] & MASK_INF) == MASK_INF) {
1461 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
1462 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
1463 // x is -inf, so it is less than y unless y is -inf
1465 res = (((y.w[1] & MASK_INF) != MASK_INF)
1466 || (y.w[1] & MASK_SIGN) != MASK_SIGN);
1467 BID_RETURN (res);
1468 } else
1469 // x is pos_inf, no way for it to be less than y
1471 res = 0;
1472 BID_RETURN (res);
1474 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
1475 // x is finite, so if y is positive infinity, then x is less, return 0
1476 // if y is negative infinity, then x is greater, return 1
1478 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1479 BID_RETURN (res);
1482 // CONVERT X
1483 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1484 sig_x.w[0] = x.w[0];
1485 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1487 // CHECK IF X IS CANONICAL
1488 // 9999999999999999999999999999999999(decimal) =
1489 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1490 // [0, 10^34) is the 754r supported canonical range.
1491 // If the value exceeds that, it is interpreted as 0.
1492 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
1493 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
1494 && (sig_x.w[0] > 0x378d8e63ffffffffull))
1495 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1496 non_canon_x = 1;
1497 else
1498 non_canon_x = 0;
1500 // CONVERT Y
1501 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1502 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1503 sig_y.w[0] = y.w[0];
1505 // CHECK IF Y IS CANONICAL
1506 // 9999999999999999999999999999999999(decimal) =
1507 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1508 // [0, 10^34) is the 754r supported canonical range.
1509 // If the value exceeds that, it is interpreted as 0.
1510 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1511 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1512 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1513 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1514 non_canon_y = 1;
1515 else
1516 non_canon_y = 0;
1518 // ZERO (CASE4)
1519 // some properties:
1520 // (+ZERO == -ZERO) => therefore ignore the sign
1521 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1522 // ignore the exponent field
1523 // (Any non-canonical # is considered 0)
1524 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1525 x_is_zero = 1;
1527 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1528 y_is_zero = 1;
1530 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
1531 if (x_is_zero && y_is_zero) {
1532 res = 0;
1533 BID_RETURN (res);
1535 // is x is zero, it is greater if Y is negative
1536 else if (x_is_zero) {
1537 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1538 BID_RETURN (res);
1540 // is y is zero, X is greater if it is positive
1541 else if (y_is_zero) {
1542 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1543 BID_RETURN (res);
1545 // OPPOSITE SIGN (CASE5)
1546 // now, if the sign bits differ, x is greater if y is negative
1547 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
1548 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1549 BID_RETURN (res);
1551 // REDUNDANT REPRESENTATIONS (CASE6)
1552 // if exponents are the same, then we have a simple comparison
1553 // of the significands
1554 if (exp_y == exp_x) {
1555 res = (((sig_x.w[1] > sig_y.w[1])
1556 || (sig_x.w[1] == sig_y.w[1]
1557 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
1558 MASK_SIGN));
1559 BID_RETURN (res);
1561 // if both components are either bigger or smaller,
1562 // it is clear what needs to be done
1563 if ((sig_x.w[1] > sig_y.w[1]
1564 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1565 && exp_x >= exp_y) {
1566 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1567 BID_RETURN (res);
1569 if ((sig_x.w[1] < sig_y.w[1]
1570 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1571 && exp_x <= exp_y) {
1572 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1573 BID_RETURN (res);
1576 diff = exp_x - exp_y;
1578 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1579 if (diff > 0) { // to simplify the loop below,
1581 // if exp_x is 33 greater than exp_y, no need for compensation
1582 if (diff > 33) {
1583 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1584 BID_RETURN (res);
1585 } // difference cannot be greater than 10^33
1587 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1588 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
1591 // if postitive, return whichever significand is larger
1592 // (converse if negative)
1593 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1594 && sig_n_prime256.w[1] == sig_y.w[1]
1595 && (sig_n_prime256.w[0] == sig_y.w[0])) {
1596 res = 0;
1597 BID_RETURN (res);
1598 } // if equal, return 0
1600 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
1601 || (sig_n_prime256.w[1] > sig_y.w[1])
1602 || (sig_n_prime256.w[1] == sig_y.w[1]
1603 && sig_n_prime256.w[0] >
1604 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
1605 BID_RETURN (res);
1608 //else { //128 by 64 bit multiply -> 192 bits
1609 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
1611 // if postitive, return whichever significand is larger
1612 // (converse if negative)
1613 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
1614 && (sig_n_prime192.w[0] == sig_y.w[0])) {
1615 res = 0;
1616 BID_RETURN (res);
1617 } // if equal, return 0
1619 res = (((sig_n_prime192.w[2] > 0)
1620 || (sig_n_prime192.w[1] > sig_y.w[1])
1621 || (sig_n_prime192.w[1] == sig_y.w[1]
1622 && sig_n_prime192.w[0] >
1623 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
1624 BID_RETURN (res);
1628 diff = exp_y - exp_x;
1630 // if exp_x is 33 less than exp_y, no need for compensation
1631 if (diff > 33) {
1632 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1633 BID_RETURN (res);
1636 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1637 // adjust the y significand upwards
1638 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
1641 // if postitive, return whichever significand is larger
1642 // (converse if negative)
1643 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1644 && sig_n_prime256.w[1] == sig_x.w[1]
1645 && (sig_n_prime256.w[0] == sig_x.w[0])) {
1646 res = 0;
1647 BID_RETURN (res);
1648 } // if equal, return 1
1650 res =
1651 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
1652 || (sig_n_prime256.w[1] > sig_x.w[1]
1653 || (sig_n_prime256.w[1] == sig_x.w[1]
1654 && sig_n_prime256.w[0] >
1655 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
1656 BID_RETURN (res);
1659 //else { //128 by 64 bit multiply -> 192 bits
1660 // adjust the y significand upwards
1661 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
1663 // if postitive, return whichever significand is larger
1664 // (converse if negative)
1665 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
1666 && (sig_n_prime192.w[0] == sig_x.w[0])) {
1667 res = 0;
1668 BID_RETURN (res);
1669 } // if equal, return 0
1671 res = (sig_n_prime192.w[2] != 0
1672 || (sig_n_prime192.w[1] > sig_x.w[1]
1673 || (sig_n_prime192.w[1] == sig_x.w[1]
1674 && sig_n_prime192.w[0] >
1675 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
1676 BID_RETURN (res);
1680 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_not_equal,
1681 x, y)
1683 int res;
1684 int exp_x, exp_y, exp_t;
1685 UINT128 sig_x, sig_y, sig_t;
1686 UINT192 sig_n_prime192;
1687 UINT256 sig_n_prime256;
1688 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
1690 // NaN (CASE1)
1691 // if either number is NAN, the comparison is unordered,
1692 // rather than equal : return 0
1693 if (((x.w[1] & MASK_NAN) == MASK_NAN)
1694 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
1695 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
1696 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
1697 *pfpsf |= INVALID_EXCEPTION;
1700 res = 1;
1701 BID_RETURN (res);
1704 // SIMPLE (CASE2)
1705 // if all the bits are the same, these numbers are equivalent.
1706 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
1707 res = 0;
1708 BID_RETURN (res);
1710 // INFINITY (CASE3)
1711 if ((x.w[1] & MASK_INF) == MASK_INF) {
1712 if ((y.w[1] & MASK_INF) == MASK_INF) {
1713 res = (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN);
1714 BID_RETURN (res);
1715 } else {
1716 res = 1;
1717 BID_RETURN (res);
1720 if ((y.w[1] & MASK_INF) == MASK_INF) {
1721 res = 1;
1722 BID_RETURN (res);
1724 // CONVERT X
1725 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1726 sig_x.w[0] = x.w[0];
1727 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1729 // CHECK IF X IS CANONICAL
1730 // 9999999999999999999999999999999999(decimal) =
1731 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1732 // [0, 10^34) is the 754r supported canonical range.
1733 // If the value exceeds that, it is interpreted as 0.
1734 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
1735 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
1736 && (sig_x.w[0] > 0x378d8e63ffffffffull))
1737 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1738 non_canon_x = 1;
1739 else
1740 non_canon_x = 0;
1742 // CONVERT Y
1743 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1744 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1745 sig_y.w[0] = y.w[0];
1747 // CHECK IF Y IS CANONICAL
1748 // 9999999999999999999999999999999999(decimal) =
1749 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1750 // [0, 10^34) is the 754r supported canonical range.
1751 // If the value exceeds that, it is interpreted as 0.
1752 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1753 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1754 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1755 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1756 non_canon_y = 1;
1757 else
1758 non_canon_y = 0;
1760 // some properties:
1761 // (+ZERO == -ZERO) => therefore ignore the sign
1762 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1763 // ignore the exponent field
1764 // (Any non-canonical # is considered 0)
1765 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1766 x_is_zero = 1;
1768 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1769 y_is_zero = 1;
1772 if (x_is_zero && y_is_zero) {
1773 res = 0;
1774 BID_RETURN (res);
1775 } else if ((x_is_zero && !y_is_zero) || (!x_is_zero && y_is_zero)) {
1776 res = 1;
1777 BID_RETURN (res);
1779 // OPPOSITE SIGN (CASE5)
1780 // now, if the sign bits differ => not equal : return 0
1781 if ((x.w[1] ^ y.w[1]) & MASK_SIGN) {
1782 res = 1;
1783 BID_RETURN (res);
1785 // REDUNDANT REPRESENTATIONS (CASE6)
1786 if (exp_x > exp_y) { // to simplify the loop below,
1787 SWAP (exp_x, exp_y, exp_t); // put the larger exp in y,
1788 SWAP (sig_x.w[1], sig_y.w[1], sig_t.w[1]); // and the smaller exp in x
1789 SWAP (sig_x.w[0], sig_y.w[0], sig_t.w[0]); // and the smaller exp in x
1793 if (exp_y - exp_x > 33) {
1794 res = 1;
1795 BID_RETURN (res);
1796 } // difference cannot be greater than 10^33
1798 if (exp_y - exp_x > 19) {
1799 // recalculate y's significand upwards
1800 __mul_128x128_to_256 (sig_n_prime256, sig_y,
1801 ten2k128[exp_y - exp_x - 20]);
1803 res = ((sig_n_prime256.w[3] != 0) || (sig_n_prime256.w[2] != 0)
1804 || (sig_n_prime256.w[1] != sig_x.w[1])
1805 || (sig_n_prime256.w[0] != sig_x.w[0]));
1806 BID_RETURN (res);
1810 //else{
1811 // recalculate y's significand upwards
1812 __mul_64x128_to192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y);
1814 res = ((sig_n_prime192.w[2] != 0)
1815 || (sig_n_prime192.w[1] != sig_x.w[1])
1816 || (sig_n_prime192.w[0] != sig_x.w[0]));
1817 BID_RETURN (res);
1821 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_not_greater,
1822 x, y)
1824 int res;
1825 int exp_x, exp_y;
1826 int diff;
1827 UINT128 sig_x, sig_y;
1828 UINT192 sig_n_prime192;
1829 UINT256 sig_n_prime256;
1830 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
1832 // NaN (CASE1)
1833 // if either number is NAN, the comparison is unordered,
1834 // rather than equal : return 0
1835 if (((x.w[1] & MASK_NAN) == MASK_NAN)
1836 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
1837 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
1838 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
1839 *pfpsf |= INVALID_EXCEPTION;
1842 res = 1;
1843 BID_RETURN (res);
1846 // SIMPLE (CASE2)
1847 // if all the bits are the same, these numbers are equal (not Greater).
1848 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
1849 res = 1;
1850 BID_RETURN (res);
1852 // INFINITY (CASE3)
1853 if ((x.w[1] & MASK_INF) == MASK_INF) {
1854 // if x is neg infinity, there is no way it is greater than y, return 1
1855 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
1856 res = 1;
1857 BID_RETURN (res);
1859 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity
1860 else {
1861 res = (((y.w[1] & MASK_INF) == MASK_INF)
1862 && ((y.w[1] & MASK_SIGN) != MASK_SIGN));
1863 BID_RETURN (res);
1865 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
1866 // x is finite, so if y is positive infinity, then x is less, return 0
1867 // if y is negative infinity, then x is greater, return 1
1869 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1870 BID_RETURN (res);
1873 // CONVERT X
1874 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1875 sig_x.w[0] = x.w[0];
1876 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1878 // CHECK IF X IS CANONICAL
1879 // 9999999999999999999999999999999999(decimal) =
1880 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1881 // [0, 10^34) is the 754r supported canonical range.
1882 // If the value exceeds that, it is interpreted as 0.
1883 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
1884 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
1885 && (sig_x.w[0] > 0x378d8e63ffffffffull))
1886 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1887 non_canon_x = 1;
1888 else
1889 non_canon_x = 0;
1891 // CONVERT Y
1892 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1893 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1894 sig_y.w[0] = y.w[0];
1896 // CHECK IF Y IS CANONICAL
1897 // 9999999999999999999999999999999999(decimal) =
1898 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1899 // [0, 10^34) is the 754r supported canonical range.
1900 // If the value exceeds that, it is interpreted as 0.
1901 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
1902 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
1903 && (sig_y.w[0] > 0x378d8e63ffffffffull))
1904 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
1905 non_canon_y = 1;
1906 else
1907 non_canon_y = 0;
1909 // ZERO (CASE4)
1910 // some properties:
1911 // (+ZERO == -ZERO) => therefore ignore the sign
1912 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
1913 // ignore the exponent field
1914 // (Any non-canonical # is considered 0)
1915 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1916 x_is_zero = 1;
1918 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1919 y_is_zero = 1;
1921 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
1922 if (x_is_zero && y_is_zero) {
1923 res = 1;
1924 BID_RETURN (res);
1926 // is x is zero, it is greater if Y is negative
1927 else if (x_is_zero) {
1928 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1929 BID_RETURN (res);
1931 // is y is zero, X is greater if it is positive
1932 else if (y_is_zero) {
1933 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1934 BID_RETURN (res);
1936 // OPPOSITE SIGN (CASE5)
1937 // now, if the sign bits differ, x is greater if y is negative
1938 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
1939 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
1940 BID_RETURN (res);
1942 // REDUNDANT REPRESENTATIONS (CASE6)
1943 // if exponents are the same, then we have a simple comparison
1944 // of the significands
1945 if (exp_y == exp_x) {
1946 res = (((sig_x.w[1] > sig_y.w[1])
1947 || (sig_x.w[1] == sig_y.w[1]
1948 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
1949 MASK_SIGN));
1950 BID_RETURN (res);
1952 // if both components are either bigger or smaller,
1953 // it is clear what needs to be done
1954 if ((sig_x.w[1] > sig_y.w[1]
1955 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1956 && exp_x >= exp_y) {
1957 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1958 BID_RETURN (res);
1960 if ((sig_x.w[1] < sig_y.w[1]
1961 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1962 && exp_x <= exp_y) {
1963 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
1964 BID_RETURN (res);
1967 diff = exp_x - exp_y;
1969 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1970 if (diff > 0) { // to simplify the loop below,
1972 // if exp_x is 33 greater than exp_y, no need for compensation
1973 if (diff > 33) {
1974 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
1975 BID_RETURN (res);
1976 } // difference cannot be greater than 10^33
1978 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1979 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
1982 // if postitive, return whichever significand is larger
1983 // (converse if negative)
1984 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
1985 && sig_n_prime256.w[1] == sig_y.w[1]
1986 && (sig_n_prime256.w[0] == sig_y.w[0])) {
1987 res = 1;
1988 BID_RETURN (res);
1989 } // if equal, return 0
1991 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
1992 || (sig_n_prime256.w[1] > sig_y.w[1])
1993 || (sig_n_prime256.w[1] == sig_y.w[1]
1994 && sig_n_prime256.w[0] >
1995 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
1996 BID_RETURN (res);
1999 //else { //128 by 64 bit multiply -> 192 bits
2000 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
2002 // if postitive, return whichever significand is larger
2003 // (converse if negative)
2004 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
2005 && (sig_n_prime192.w[0] == sig_y.w[0])) {
2006 res = 1;
2007 BID_RETURN (res);
2008 } // if equal, return 0
2010 res = (((sig_n_prime192.w[2] > 0)
2011 || (sig_n_prime192.w[1] > sig_y.w[1])
2012 || (sig_n_prime192.w[1] == sig_y.w[1]
2013 && sig_n_prime192.w[0] >
2014 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
2015 BID_RETURN (res);
2019 diff = exp_y - exp_x;
2021 // if exp_x is 33 less than exp_y, no need for compensation
2022 if (diff > 33) {
2023 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2024 BID_RETURN (res);
2027 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2028 // adjust the y significand upwards
2029 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
2032 // if postitive, return whichever significand is larger
2033 // (converse if negative)
2034 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
2035 && sig_n_prime256.w[1] == sig_x.w[1]
2036 && (sig_n_prime256.w[0] == sig_x.w[0])) {
2037 res = 1;
2038 BID_RETURN (res);
2039 } // if equal, return 0
2041 res =
2042 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
2043 || (sig_n_prime256.w[1] > sig_x.w[1]
2044 || (sig_n_prime256.w[1] == sig_x.w[1]
2045 && sig_n_prime256.w[0] >
2046 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
2047 BID_RETURN (res);
2050 //else { //128 by 64 bit multiply -> 192 bits
2051 // adjust the y significand upwards
2052 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
2054 // if postitive, return whichever significand is larger
2055 // (converse if negative)
2056 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
2057 && (sig_n_prime192.w[0] == sig_x.w[0])) {
2058 res = 1;
2059 BID_RETURN (res);
2060 } // if equal, return 0
2062 res = (sig_n_prime192.w[2] != 0
2063 || (sig_n_prime192.w[1] > sig_x.w[1]
2064 || (sig_n_prime192.w[1] == sig_x.w[1]
2065 && sig_n_prime192.w[0] >
2066 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2067 BID_RETURN (res);
2071 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_not_less, x,
2074 int res;
2075 int exp_x, exp_y;
2076 int diff;
2077 UINT128 sig_x, sig_y;
2078 UINT192 sig_n_prime192;
2079 UINT256 sig_n_prime256;
2080 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
2082 // NaN (CASE1)
2083 // if either number is NAN, the comparison is unordered,
2084 // rather than equal : return 1
2085 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2086 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2087 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
2088 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
2089 *pfpsf |= INVALID_EXCEPTION;
2092 res = 1;
2093 BID_RETURN (res);
2096 // SIMPLE (CASE2)
2097 // if all the bits are the same, these numbers are equal (not Greater).
2098 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
2099 res = 1;
2100 BID_RETURN (res);
2102 // INFINITY (CASE3)
2103 if ((x.w[1] & MASK_INF) == MASK_INF) {
2104 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
2105 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
2106 // x is -inf, so it is less than y unless y is -inf
2108 res = (((y.w[1] & MASK_INF) == MASK_INF)
2109 && (y.w[1] & MASK_SIGN) == MASK_SIGN);
2110 BID_RETURN (res);
2111 } else
2112 // x is pos_inf, no way for it to be less than y
2114 res = 1;
2115 BID_RETURN (res);
2117 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
2118 // x is finite, so if y is positive infinity, then x is less, return 0
2119 // if y is negative infinity, then x is greater, return 1
2121 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2122 BID_RETURN (res);
2125 // CONVERT X
2126 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
2127 sig_x.w[0] = x.w[0];
2128 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
2130 // CHECK IF X IS CANONICAL
2131 // 9999999999999999999999999999999999(decimal) =
2132 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2133 // [0, 10^34) is the 754r supported canonical range.
2134 // If the value exceeds that, it is interpreted as 0.
2135 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
2136 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
2137 && (sig_x.w[0] > 0x378d8e63ffffffffull))
2138 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2139 non_canon_x = 1;
2140 else
2141 non_canon_x = 0;
2143 // CONVERT Y
2144 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
2145 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
2146 sig_y.w[0] = y.w[0];
2148 // CHECK IF Y IS CANONICAL
2149 // 9999999999999999999999999999999999(decimal) =
2150 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2151 // [0, 10^34) is the 754r supported canonical range.
2152 // If the value exceeds that, it is interpreted as 0.
2153 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
2154 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
2155 && (sig_y.w[0] > 0x378d8e63ffffffffull))
2156 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2157 non_canon_y = 1;
2158 else
2159 non_canon_y = 0;
2161 // ZERO (CASE4)
2162 // some properties:
2163 // (+ZERO == -ZERO) => therefore ignore the sign
2164 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
2165 // ignore the exponent field
2166 // (Any non-canonical # is considered 0)
2167 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
2168 x_is_zero = 1;
2170 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
2171 y_is_zero = 1;
2173 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
2174 if (x_is_zero && y_is_zero) {
2175 res = 1;
2176 BID_RETURN (res);
2178 // is x is zero, it is greater if Y is negative
2179 else if (x_is_zero) {
2180 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2181 BID_RETURN (res);
2183 // is y is zero, X is greater if it is positive
2184 else if (y_is_zero) {
2185 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2186 BID_RETURN (res);
2188 // OPPOSITE SIGN (CASE5)
2189 // now, if the sign bits differ, x is greater if y is negative
2190 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
2191 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2192 BID_RETURN (res);
2194 // REDUNDANT REPRESENTATIONS (CASE6)
2196 // if exponents are the same, then we have a simple comparison
2197 // of the significands
2198 if (exp_y == exp_x) {
2199 res = (((sig_x.w[1] > sig_y.w[1])
2200 || (sig_x.w[1] == sig_y.w[1]
2201 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
2202 MASK_SIGN));
2203 BID_RETURN (res);
2205 // if both components are either bigger or smaller,
2206 // it is clear what needs to be done
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);
2212 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
2213 && exp_x < exp_y) {
2214 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2215 BID_RETURN (res);
2218 diff = exp_x - exp_y;
2220 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
2221 if (diff > 0) { // to simplify the loop below,
2223 // if exp_x is 33 greater than exp_y, no need for compensation
2224 if (diff > 33) {
2225 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2226 BID_RETURN (res);
2227 } // difference cannot be greater than 10^33
2229 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2230 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
2233 // if postitive, return whichever significand is larger
2234 // (converse if negative)
2235 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
2236 && sig_n_prime256.w[1] == sig_y.w[1]
2237 && (sig_n_prime256.w[0] == sig_y.w[0])) {
2238 res = 1;
2239 BID_RETURN (res);
2240 } // if equal, return 1
2242 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
2243 || (sig_n_prime256.w[1] > sig_y.w[1])
2244 || (sig_n_prime256.w[1] == sig_y.w[1]
2245 && sig_n_prime256.w[0] >
2246 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
2247 BID_RETURN (res);
2250 //else { //128 by 64 bit multiply -> 192 bits
2251 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
2253 // if postitive, return whichever significand is larger
2254 // (converse if negative)
2255 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
2256 && (sig_n_prime192.w[0] == sig_y.w[0])) {
2257 res = 1;
2258 BID_RETURN (res);
2259 } // if equal, return 1
2261 res = (((sig_n_prime192.w[2] > 0)
2262 || (sig_n_prime192.w[1] > sig_y.w[1])
2263 || (sig_n_prime192.w[1] == sig_y.w[1]
2264 && sig_n_prime192.w[0] >
2265 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
2266 BID_RETURN (res);
2270 diff = exp_y - exp_x;
2272 // if exp_x is 33 less than exp_y, no need for compensation
2273 if (diff > 33) {
2274 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2275 BID_RETURN (res);
2278 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2279 // adjust the y significand upwards
2280 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
2283 // if postitive, return whichever significand is larger
2284 // (converse if negative)
2285 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
2286 && sig_n_prime256.w[1] == sig_x.w[1]
2287 && (sig_n_prime256.w[0] == sig_x.w[0])) {
2288 res = 1;
2289 BID_RETURN (res);
2290 } // if equal, return 1
2292 res =
2293 ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
2294 && (sig_n_prime256.w[1] < sig_x.w[1]
2295 || (sig_n_prime256.w[1] == sig_x.w[1]
2296 && sig_n_prime256.w[0] <
2297 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
2298 BID_RETURN (res);
2301 //else { //128 by 64 bit multiply -> 192 bits
2302 // adjust the y significand upwards
2303 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
2305 // if postitive, return whichever significand is larger
2306 // (converse if negative)
2307 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
2308 && (sig_n_prime192.w[0] == sig_x.w[0])) {
2309 res = 1;
2310 BID_RETURN (res);
2311 } // if equal, return 1
2313 res = (sig_n_prime192.w[2] == 0
2314 && (sig_n_prime192.w[1] < sig_x.w[1]
2315 || (sig_n_prime192.w[1] == sig_x.w[1]
2316 && sig_n_prime192.w[0] <
2317 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2318 BID_RETURN (res);
2322 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_ordered, x,
2325 int res;
2327 // NaN (CASE1)
2328 // if either number is NAN, the comparison is ordered : return 1
2329 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2330 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2331 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
2332 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
2333 *pfpsf |= INVALID_EXCEPTION;
2336 res = 0;
2337 BID_RETURN (res);
2341 res = 1;
2342 BID_RETURN (res);
2346 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_quiet_unordered,
2347 x, y)
2349 int res;
2351 // NaN (CASE1)
2352 // if either number is NAN, the comparison is unordered : return 1
2353 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2354 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2355 if ((x.w[1] & MASK_SNAN) == MASK_SNAN
2356 || (y.w[1] & MASK_SNAN) == MASK_SNAN) {
2357 *pfpsf |= INVALID_EXCEPTION;
2360 res = 1;
2361 BID_RETURN (res);
2365 res = 0;
2366 BID_RETURN (res);
2370 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_signaling_greater,
2371 x, y)
2373 int res;
2374 int exp_x, exp_y;
2375 int diff;
2376 UINT128 sig_x, sig_y;
2377 UINT192 sig_n_prime192;
2378 UINT256 sig_n_prime256;
2379 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
2381 // NaN (CASE1)
2382 // if either number is NAN, the comparison is unordered,
2383 // rather than equal : return 0
2384 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2385 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2386 *pfpsf |= INVALID_EXCEPTION;
2388 res = 0;
2389 BID_RETURN (res);
2392 // SIMPLE (CASE2)
2393 // if all the bits are the same, these numbers are equal (not Greater).
2394 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
2395 res = 0;
2396 BID_RETURN (res);
2398 // INFINITY (CASE3)
2399 if ((x.w[1] & MASK_INF) == MASK_INF) {
2400 // if x is neg infinity, there is no way it is greater than y, return 0
2401 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
2402 res = 0;
2403 BID_RETURN (res);
2405 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity
2406 else {
2407 res = (((y.w[1] & MASK_INF) != MASK_INF)
2408 || ((y.w[1] & MASK_SIGN) == MASK_SIGN));
2409 BID_RETURN (res);
2411 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
2412 // x is finite, so if y is positive infinity, then x is less, return 0
2413 // if y is negative infinity, then x is greater, return 1
2415 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2416 BID_RETURN (res);
2419 // CONVERT X
2420 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
2421 sig_x.w[0] = x.w[0];
2422 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
2424 // CHECK IF X IS CANONICAL
2425 // 9999999999999999999999999999999999(decimal) =
2426 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2427 // [0, 10^34) is the 754r supported canonical range.
2428 // If the value exceeds that, it is interpreted as 0.
2429 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
2430 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
2431 && (sig_x.w[0] > 0x378d8e63ffffffffull))
2432 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2433 non_canon_x = 1;
2434 else
2435 non_canon_x = 0;
2437 // CONVERT Y
2438 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
2439 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
2440 sig_y.w[0] = y.w[0];
2442 // CHECK IF Y IS CANONICAL
2443 // 9999999999999999999999999999999999(decimal) =
2444 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2445 // [0, 10^34) is the 754r supported canonical range.
2446 // If the value exceeds that, it is interpreted as 0.
2447 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
2448 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
2449 && (sig_y.w[0] > 0x378d8e63ffffffffull))
2450 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2451 non_canon_y = 1;
2452 else
2453 non_canon_y = 0;
2455 // ZERO (CASE4)
2456 // some properties:
2457 // (+ZERO == -ZERO) => therefore ignore the sign
2458 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
2459 // ignore the exponent field
2460 // (Any non-canonical # is considered 0)
2461 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
2462 x_is_zero = 1;
2464 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
2465 y_is_zero = 1;
2467 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
2468 if (x_is_zero && y_is_zero) {
2469 res = 0;
2470 BID_RETURN (res);
2472 // is x is zero, it is greater if Y is negative
2473 else if (x_is_zero) {
2474 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2475 BID_RETURN (res);
2477 // is y is zero, X is greater if it is positive
2478 else if (y_is_zero) {
2479 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2480 BID_RETURN (res);
2482 // OPPOSITE SIGN (CASE5)
2483 // now, if the sign bits differ, x is greater if y is negative
2484 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
2485 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2486 BID_RETURN (res);
2488 // REDUNDANT REPRESENTATIONS (CASE6)
2489 // if exponents are the same, then we have a simple comparison
2490 // of the significands
2491 if (exp_y == exp_x) {
2492 res = (((sig_x.w[1] > sig_y.w[1])
2493 || (sig_x.w[1] == sig_y.w[1]
2494 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
2495 MASK_SIGN));
2496 BID_RETURN (res);
2498 // if both components are either bigger or smaller,
2499 // it is clear what needs to be done
2500 if ((sig_x.w[1] > sig_y.w[1]
2501 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
2502 && exp_x >= exp_y) {
2504 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2505 BID_RETURN (res);
2508 if ((sig_x.w[1] < sig_y.w[1]
2509 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
2510 && exp_x <= exp_y) {
2512 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2513 BID_RETURN (res);
2517 diff = exp_x - exp_y;
2519 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
2520 if (diff > 0) { // to simplify the loop below,
2522 // if exp_x is 33 greater than exp_y, no need for compensation
2523 if (diff > 33) {
2524 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2525 BID_RETURN (res);
2526 } // difference cannot be greater than 10^33
2528 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2529 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
2531 // if postitive, return whichever significand is larger
2532 // (converse if negative)
2533 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
2534 && sig_n_prime256.w[1] == sig_y.w[1]
2535 && (sig_n_prime256.w[0] == sig_y.w[0])) {
2536 res = 0;
2537 BID_RETURN (res);
2538 } // if equal, return 0
2540 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
2541 || (sig_n_prime256.w[1] > sig_y.w[1])
2542 || (sig_n_prime256.w[1] == sig_y.w[1]
2543 && sig_n_prime256.w[0] >
2544 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
2545 BID_RETURN (res);
2548 //else { //128 by 64 bit multiply -> 192 bits
2549 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
2551 // if postitive, return whichever significand is larger
2552 // (converse if negative)
2553 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
2554 && (sig_n_prime192.w[0] == sig_y.w[0])) {
2555 res = 0;
2556 BID_RETURN (res);
2557 } // if equal, return 0
2559 res = (((sig_n_prime192.w[2] > 0)
2560 || (sig_n_prime192.w[1] > sig_y.w[1])
2561 || (sig_n_prime192.w[1] == sig_y.w[1]
2562 && sig_n_prime192.w[0] >
2563 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
2564 BID_RETURN (res);
2568 diff = exp_y - exp_x;
2570 // if exp_x is 33 less than exp_y, no need for compensation
2571 if (diff > 33) {
2572 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2573 BID_RETURN (res);
2576 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2577 // adjust the y significand upwards
2578 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
2580 // if postitive, return whichever significand is larger
2581 // (converse if negative)
2582 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
2583 && sig_n_prime256.w[1] == sig_x.w[1]
2584 && (sig_n_prime256.w[0] == sig_x.w[0])) {
2585 res = 0;
2586 BID_RETURN (res);
2587 } // if equal, return 0
2589 res =
2590 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
2591 || (sig_n_prime256.w[1] > sig_x.w[1]
2592 || (sig_n_prime256.w[1] == sig_x.w[1]
2593 && sig_n_prime256.w[0] >
2594 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) != MASK_SIGN));
2595 BID_RETURN (res);
2598 //else { //128 by 64 bit multiply -> 192 bits
2599 // adjust the y significand upwards
2600 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
2602 // if postitive, return whichever significand is larger
2603 // (converse if negative)
2604 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
2605 && (sig_n_prime192.w[0] == sig_x.w[0])) {
2606 res = 0;
2607 BID_RETURN (res);
2608 } // if equal, return 0
2610 res = (sig_n_prime192.w[2] != 0
2611 || (sig_n_prime192.w[1] > sig_x.w[1]
2612 || (sig_n_prime192.w[1] == sig_x.w[1]
2613 && sig_n_prime192.w[0] >
2614 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN);
2615 BID_RETURN (res);
2619 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
2620 bid128_signaling_greater_equal,
2621 x, y)
2623 int res;
2624 int exp_x, exp_y;
2625 int diff;
2626 UINT128 sig_x, sig_y;
2627 UINT192 sig_n_prime192;
2628 UINT256 sig_n_prime256;
2629 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
2631 // NaN (CASE1)
2632 // if either number is NAN, the comparison is unordered,
2633 // rather than equal : return 1
2634 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2635 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2636 *pfpsf |= INVALID_EXCEPTION;
2638 res = 0;
2639 BID_RETURN (res);
2642 // SIMPLE (CASE2)
2643 // if all the bits are the same, these numbers are equal (not Greater).
2644 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
2645 res = 1;
2646 BID_RETURN (res);
2648 // INFINITY (CASE3)
2649 if ((x.w[1] & MASK_INF) == MASK_INF) {
2650 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
2651 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
2652 // x is -inf, so it is less than y unless y is -inf
2654 res = (((y.w[1] & MASK_INF) == MASK_INF)
2655 && (y.w[1] & MASK_SIGN) == MASK_SIGN);
2656 BID_RETURN (res);
2657 } else
2658 // x is pos_inf, no way for it to be less than y
2660 res = 1;
2661 BID_RETURN (res);
2663 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
2664 // x is finite, so if y is positive infinity, then x is less, return 0
2665 // if y is negative infinity, then x is greater, return 1
2667 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2668 BID_RETURN (res);
2671 // CONVERT X
2672 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
2673 sig_x.w[0] = x.w[0];
2674 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
2676 // CHECK IF X IS CANONICAL
2677 // 9999999999999999999999999999999999(decimal) =
2678 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2679 // [0, 10^34) is the 754r supported canonical range.
2680 // If the value exceeds that, it is interpreted as 0.
2681 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
2682 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
2683 && (sig_x.w[0] > 0x378d8e63ffffffffull))
2684 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2685 non_canon_x = 1;
2686 else
2687 non_canon_x = 0;
2689 // CONVERT Y
2690 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
2691 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
2692 sig_y.w[0] = y.w[0];
2694 // CHECK IF Y IS CANONICAL
2695 // 9999999999999999999999999999999999(decimal) =
2696 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2697 // [0, 10^34) is the 754r supported canonical range.
2698 // If the value exceeds that, it is interpreted as 0.
2699 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
2700 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
2701 && (sig_y.w[0] > 0x378d8e63ffffffffull))
2702 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2703 non_canon_y = 1;
2704 else
2705 non_canon_y = 0;
2707 // ZERO (CASE4)
2708 // some properties:
2709 // (+ZERO == -ZERO) => therefore ignore the sign
2710 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
2711 // ignore the exponent field
2712 // (Any non-canonical # is considered 0)
2713 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
2714 x_is_zero = 1;
2716 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
2717 y_is_zero = 1;
2719 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
2720 if (x_is_zero && y_is_zero) {
2721 res = 1;
2722 BID_RETURN (res);
2724 // is x is zero, it is greater if Y is negative
2725 else if (x_is_zero) {
2726 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2727 BID_RETURN (res);
2729 // is y is zero, X is greater if it is positive
2730 else if (y_is_zero) {
2731 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2732 BID_RETURN (res);
2734 // OPPOSITE SIGN (CASE5)
2735 // now, if the sign bits differ, x is greater if y is negative
2736 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
2737 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2738 BID_RETURN (res);
2740 // REDUNDANT REPRESENTATIONS (CASE6)
2741 // if exponents are the same, then we have a simple comparison
2742 // of the significands
2743 if (exp_y == exp_x) {
2744 res = (((sig_x.w[1] > sig_y.w[1])
2745 || (sig_x.w[1] == sig_y.w[1]
2746 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
2747 MASK_SIGN));
2748 BID_RETURN (res);
2750 // if both components are either bigger or smaller,
2751 // it is clear what needs to be done
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);
2757 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
2758 && exp_x < exp_y) {
2759 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2760 BID_RETURN (res);
2763 diff = exp_x - exp_y;
2765 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
2766 if (diff > 0) { // to simplify the loop below,
2768 // if exp_x is 33 greater than exp_y, no need for compensation
2769 if (diff > 33) {
2770 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2771 BID_RETURN (res);
2772 } // difference cannot be greater than 10^33
2774 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2775 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
2778 // if postitive, return whichever significand is larger
2779 // (converse if negative)
2780 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
2781 && sig_n_prime256.w[1] == sig_y.w[1]
2782 && (sig_n_prime256.w[0] == sig_y.w[0])) {
2783 res = 1;
2784 BID_RETURN (res);
2785 } // if equal, return 1
2787 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
2788 || (sig_n_prime256.w[1] > sig_y.w[1])
2789 || (sig_n_prime256.w[1] == sig_y.w[1]
2790 && sig_n_prime256.w[0] >
2791 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
2792 BID_RETURN (res);
2795 //else { //128 by 64 bit multiply -> 192 bits
2796 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
2798 // if postitive, return whichever significand is larger
2799 // (converse if negative)
2800 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
2801 && (sig_n_prime192.w[0] == sig_y.w[0])) {
2802 res = 1;
2803 BID_RETURN (res);
2804 } // if equal, return 1
2806 res = (((sig_n_prime192.w[2] > 0)
2807 || (sig_n_prime192.w[1] > sig_y.w[1])
2808 || (sig_n_prime192.w[1] == sig_y.w[1]
2809 && sig_n_prime192.w[0] >
2810 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
2811 BID_RETURN (res);
2815 diff = exp_y - exp_x;
2817 // if exp_x is 33 less than exp_y, no need for compensation
2818 if (diff > 33) {
2819 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
2820 BID_RETURN (res);
2823 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
2824 // adjust the y significand upwards
2825 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
2828 // if postitive, return whichever significand is larger
2829 // (converse if negative)
2830 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
2831 && sig_n_prime256.w[1] == sig_x.w[1]
2832 && (sig_n_prime256.w[0] == sig_x.w[0])) {
2833 res = 1;
2834 BID_RETURN (res);
2835 } // if equal, return 1
2837 res =
2838 ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
2839 && (sig_n_prime256.w[1] < sig_x.w[1]
2840 || (sig_n_prime256.w[1] == sig_x.w[1]
2841 && sig_n_prime256.w[0] <
2842 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
2843 BID_RETURN (res);
2846 //else { //128 by 64 bit multiply -> 192 bits
2847 // adjust the y significand upwards
2848 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
2850 // if postitive, return whichever significand is larger
2851 // (converse if negative)
2852 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
2853 && (sig_n_prime192.w[0] == sig_x.w[0])) {
2854 res = 1;
2855 BID_RETURN (res);
2856 } // if equal, return 1
2858 res = (sig_n_prime192.w[2] == 0
2859 && (sig_n_prime192.w[1] < sig_x.w[1]
2860 || (sig_n_prime192.w[1] == sig_x.w[1]
2861 && sig_n_prime192.w[0] <
2862 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2863 BID_RETURN (res);
2867 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
2868 bid128_signaling_greater_unordered,
2869 x, y)
2871 int res;
2872 int exp_x, exp_y;
2873 int diff;
2874 UINT128 sig_x, sig_y;
2875 UINT192 sig_n_prime192;
2876 UINT256 sig_n_prime256;
2877 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
2879 // NaN (CASE1)
2880 // if either number is NAN, the comparison is unordered,
2881 // rather than equal : return 1
2882 if (((x.w[1] & MASK_NAN) == MASK_NAN)
2883 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
2884 *pfpsf |= INVALID_EXCEPTION;
2886 res = 1;
2887 BID_RETURN (res);
2890 // SIMPLE (CASE2)
2891 // if all the bits are the same, these numbers are equal (not Greater).
2892 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
2893 res = 0;
2894 BID_RETURN (res);
2896 // INFINITY (CASE3)
2897 if ((x.w[1] & MASK_INF) == MASK_INF) {
2898 // if x is neg infinity, there is no way it is greater than y, return 0
2899 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
2900 res = 0;
2901 BID_RETURN (res);
2903 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity
2904 else {
2905 res = (((y.w[1] & MASK_INF) != MASK_INF)
2906 || ((y.w[1] & MASK_SIGN) == MASK_SIGN));
2907 BID_RETURN (res);
2909 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
2910 // x is finite, so if y is positive infinity, then x is less, return 0
2911 // if y is negative infinity, then x is greater, return 1
2913 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2914 BID_RETURN (res);
2917 // CONVERT X
2918 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
2919 sig_x.w[0] = x.w[0];
2920 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
2922 // CHECK IF X IS CANONICAL
2923 // 9999999999999999999999999999999999(decimal) =
2924 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2925 // [0, 10^34) is the 754r supported canonical range.
2926 // If the value exceeds that, it is interpreted as 0.
2927 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
2928 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
2929 && (sig_x.w[0] > 0x378d8e63ffffffffull))
2930 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2931 non_canon_x = 1;
2932 else
2933 non_canon_x = 0;
2935 // CONVERT Y
2936 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
2937 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
2938 sig_y.w[0] = y.w[0];
2940 // CHECK IF Y IS CANONICAL
2941 // 9999999999999999999999999999999999(decimal) =
2942 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
2943 // [0, 10^34) is the 754r supported canonical range.
2944 // If the value exceeds that, it is interpreted as 0.
2945 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
2946 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
2947 && (sig_y.w[0] > 0x378d8e63ffffffffull))
2948 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
2949 non_canon_y = 1;
2950 else
2951 non_canon_y = 0;
2953 // ZERO (CASE4)
2954 // some properties:
2955 // (+ZERO == -ZERO) => therefore ignore the sign
2956 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
2957 // ignore the exponent field
2958 // (Any non-canonical # is considered 0)
2959 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
2960 x_is_zero = 1;
2962 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
2963 y_is_zero = 1;
2965 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
2966 if (x_is_zero && y_is_zero) {
2967 res = 0;
2968 BID_RETURN (res);
2970 // is x is zero, it is greater if Y is negative
2971 else if (x_is_zero) {
2972 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2973 BID_RETURN (res);
2975 // is y is zero, X is greater if it is positive
2976 else if (y_is_zero) {
2977 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
2978 BID_RETURN (res);
2980 // OPPOSITE SIGN (CASE5)
2981 // now, if the sign bits differ, x is greater if y is negative
2982 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
2983 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
2984 BID_RETURN (res);
2986 // REDUNDANT REPRESENTATIONS (CASE6)
2987 // if exponents are the same, then we have a simple comparison
2988 // of the significands
2989 if (exp_y == exp_x) {
2990 res = (((sig_x.w[1] > sig_y.w[1])
2991 || (sig_x.w[1] == sig_y.w[1]
2992 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
2993 MASK_SIGN));
2994 BID_RETURN (res);
2996 // if both components are either bigger or smaller,
2997 // it is clear what needs to be done
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);
3003 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
3004 && exp_x < exp_y) {
3005 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3006 BID_RETURN (res);
3009 diff = exp_x - exp_y;
3011 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
3012 if (diff > 0) { // to simplify the loop below,
3014 // if exp_x is 33 greater than exp_y, no need for compensation
3015 if (diff > 33) {
3016 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3017 BID_RETURN (res);
3018 } // difference cannot be greater than 10^33
3020 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3021 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
3024 // if postitive, return whichever significand is larger
3025 // (converse if negative)
3026 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
3027 && sig_n_prime256.w[1] == sig_y.w[1]
3028 && (sig_n_prime256.w[0] == sig_y.w[0])) {
3029 res = 0;
3030 BID_RETURN (res);
3031 } // if equal, return 0
3033 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
3034 || (sig_n_prime256.w[1] > sig_y.w[1])
3035 || (sig_n_prime256.w[1] == sig_y.w[1]
3036 && sig_n_prime256.w[0] >
3037 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
3038 BID_RETURN (res);
3041 //else { //128 by 64 bit multiply -> 192 bits
3042 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
3044 // if postitive, return whichever significand is larger
3045 // (converse if negative)
3046 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
3047 && (sig_n_prime192.w[0] == sig_y.w[0])) {
3048 res = 0;
3049 BID_RETURN (res);
3050 } // if equal, return 0
3052 res = (((sig_n_prime192.w[2] > 0)
3053 || (sig_n_prime192.w[1] > sig_y.w[1])
3054 || (sig_n_prime192.w[1] == sig_y.w[1]
3055 && sig_n_prime192.w[0] >
3056 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
3057 BID_RETURN (res);
3061 diff = exp_y - exp_x;
3063 // if exp_x is 33 less than exp_y, no need for compensation
3064 if (diff > 33) {
3065 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3066 BID_RETURN (res);
3069 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3070 // adjust the y significand upwards
3071 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
3074 // if postitive, return whichever significand is larger
3075 // (converse if negative)
3076 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
3077 && sig_n_prime256.w[1] == sig_x.w[1]
3078 && (sig_n_prime256.w[0] == sig_x.w[0])) {
3079 res = 0;
3080 BID_RETURN (res);
3081 } // if equal, return 0
3083 res =
3084 ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
3085 && (sig_n_prime256.w[1] < sig_x.w[1]
3086 || (sig_n_prime256.w[1] == sig_x.w[1]
3087 && sig_n_prime256.w[0] <
3088 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
3089 BID_RETURN (res);
3092 //else { //128 by 64 bit multiply -> 192 bits
3093 // adjust the y significand upwards
3094 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
3096 // if postitive, return whichever significand is larger
3097 // (converse if negative)
3098 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
3099 && (sig_n_prime192.w[0] == sig_x.w[0])) {
3100 res = 0;
3101 BID_RETURN (res);
3102 } // if equal, return 0
3104 res = (sig_n_prime192.w[2] == 0
3105 && (sig_n_prime192.w[1] < sig_x.w[1]
3106 || (sig_n_prime192.w[1] == sig_x.w[1]
3107 && sig_n_prime192.w[0] <
3108 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
3109 BID_RETURN (res);
3113 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int, bid128_signaling_less, x,
3116 int res;
3117 int exp_x, exp_y;
3118 int diff;
3119 UINT128 sig_x, sig_y;
3120 UINT192 sig_n_prime192;
3121 UINT256 sig_n_prime256;
3122 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
3124 // NaN (CASE1)
3125 // if either number is NAN, the comparison is unordered,
3126 // rather than equal : return 0
3127 if (((x.w[1] & MASK_NAN) == MASK_NAN)
3128 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
3129 *pfpsf |= INVALID_EXCEPTION;
3131 res = 0;
3132 BID_RETURN (res);
3135 // SIMPLE (CASE2)
3136 // if all the bits are the same, these numbers are equal.
3137 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
3138 res = 0;
3139 BID_RETURN (res);
3141 // INFINITY (CASE3)
3142 if ((x.w[1] & MASK_INF) == MASK_INF) {
3143 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
3144 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
3145 // x is -inf, so it is less than y unless y is -inf
3147 res = (((y.w[1] & MASK_INF) != MASK_INF)
3148 || (y.w[1] & MASK_SIGN) != MASK_SIGN);
3149 BID_RETURN (res);
3150 } else
3151 // x is pos_inf, no way for it to be less than y
3153 res = 0;
3154 BID_RETURN (res);
3156 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
3157 // x is finite, so if y is positive infinity, then x is less, return 0
3158 // if y is negative infinity, then x is greater, return 1
3160 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3161 BID_RETURN (res);
3164 // CONVERT X
3165 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
3166 sig_x.w[0] = x.w[0];
3167 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
3169 // CHECK IF X IS CANONICAL
3170 // 9999999999999999999999999999999999(decimal) =
3171 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3172 // [0, 10^34) is the 754r supported canonical range.
3173 // If the value exceeds that, it is interpreted as 0.
3174 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
3175 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
3176 && (sig_x.w[0] > 0x378d8e63ffffffffull))
3177 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3178 non_canon_x = 1;
3179 else
3180 non_canon_x = 0;
3182 // CONVERT Y
3183 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
3184 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
3185 sig_y.w[0] = y.w[0];
3187 // CHECK IF Y IS CANONICAL
3188 // 9999999999999999999999999999999999(decimal) =
3189 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3190 // [0, 10^34) is the 754r supported canonical range.
3191 // If the value exceeds that, it is interpreted as 0.
3192 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
3193 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
3194 && (sig_y.w[0] > 0x378d8e63ffffffffull))
3195 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3196 non_canon_y = 1;
3197 else
3198 non_canon_y = 0;
3200 // ZERO (CASE4)
3201 // some properties:
3202 // (+ZERO == -ZERO) => therefore ignore the sign
3203 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
3204 // ignore the exponent field
3205 // (Any non-canonical # is considered 0)
3206 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
3207 x_is_zero = 1;
3209 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
3210 y_is_zero = 1;
3212 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
3213 if (x_is_zero && y_is_zero) {
3214 res = 0;
3215 BID_RETURN (res);
3217 // is x is zero, it is greater if Y is negative
3218 else if (x_is_zero) {
3219 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3220 BID_RETURN (res);
3222 // is y is zero, X is greater if it is positive
3223 else if (y_is_zero) {
3224 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3225 BID_RETURN (res);
3227 // OPPOSITE SIGN (CASE5)
3228 // now, if the sign bits differ, x is greater if y is negative
3229 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
3230 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3231 BID_RETURN (res);
3233 // REDUNDANT REPRESENTATIONS (CASE6)
3234 // if exponents are the same, then we have a simple comparison
3235 // of the significands
3236 if (exp_y == exp_x) {
3237 res = (((sig_x.w[1] > sig_y.w[1])
3238 || (sig_x.w[1] == sig_y.w[1]
3239 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
3240 MASK_SIGN));
3241 BID_RETURN (res);
3243 // if both components are either bigger or smaller,
3244 // it is clear what needs to be done
3245 if ((sig_x.w[1] > sig_y.w[1]
3246 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
3247 && exp_x >= exp_y) {
3248 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3249 BID_RETURN (res);
3251 if ((sig_x.w[1] < sig_y.w[1]
3252 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
3253 && exp_x <= exp_y) {
3254 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3255 BID_RETURN (res);
3258 diff = exp_x - exp_y;
3260 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
3261 if (diff > 0) { // to simplify the loop below,
3263 // if exp_x is 33 greater than exp_y, no need for compensation
3264 if (diff > 33) {
3265 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3266 BID_RETURN (res);
3267 } // difference cannot be greater than 10^33
3269 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3270 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
3273 // if postitive, return whichever significand is larger
3274 // (converse if negative)
3275 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
3276 && sig_n_prime256.w[1] == sig_y.w[1]
3277 && (sig_n_prime256.w[0] == sig_y.w[0])) {
3278 res = 0;
3279 BID_RETURN (res);
3280 } // if equal, return 0
3282 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
3283 || (sig_n_prime256.w[1] > sig_y.w[1])
3284 || (sig_n_prime256.w[1] == sig_y.w[1]
3285 && sig_n_prime256.w[0] >
3286 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
3287 BID_RETURN (res);
3290 //else { //128 by 64 bit multiply -> 192 bits
3291 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
3293 // if postitive, return whichever significand is larger
3294 // (converse if negative)
3295 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
3296 && (sig_n_prime192.w[0] == sig_y.w[0])) {
3297 res = 0;
3298 BID_RETURN (res);
3299 } // if equal, return 0
3301 res = (((sig_n_prime192.w[2] > 0)
3302 || (sig_n_prime192.w[1] > sig_y.w[1])
3303 || (sig_n_prime192.w[1] == sig_y.w[1]
3304 && sig_n_prime192.w[0] >
3305 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
3306 BID_RETURN (res);
3310 diff = exp_y - exp_x;
3312 // if exp_x is 33 less than exp_y, |x| < |y|, return 1 if positive
3313 if (diff > 33) {
3314 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3315 BID_RETURN (res);
3318 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3319 // adjust the y significand upwards
3320 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
3323 // if postitive, return whichever significand is larger
3324 // (converse if negative)
3325 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
3326 && sig_n_prime256.w[1] == sig_x.w[1]
3327 && (sig_n_prime256.w[0] == sig_x.w[0])) {
3328 res = 0;
3329 BID_RETURN (res);
3330 } // if equal, return 1
3332 res =
3333 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
3334 || (sig_n_prime256.w[1] > sig_x.w[1]
3335 || (sig_n_prime256.w[1] == sig_x.w[1]
3336 && sig_n_prime256.w[0] >
3337 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
3338 BID_RETURN (res);
3341 //else { //128 by 64 bit multiply -> 192 bits
3342 // adjust the y significand upwards
3343 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
3345 // if postitive, return whichever significand is larger
3346 // (converse if negative)
3347 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
3348 && (sig_n_prime192.w[0] == sig_x.w[0])) {
3349 res = 0;
3350 BID_RETURN (res);
3351 } // if equal, return 0
3353 res = (sig_n_prime192.w[2] != 0
3354 || (sig_n_prime192.w[1] > sig_x.w[1]
3355 || (sig_n_prime192.w[1] == sig_x.w[1]
3356 && sig_n_prime192.w[0] >
3357 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
3358 BID_RETURN (res);
3362 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
3363 bid128_signaling_less_equal,
3364 x, y)
3366 int res;
3367 int exp_x, exp_y;
3368 int diff;
3369 UINT128 sig_x, sig_y;
3370 UINT192 sig_n_prime192;
3371 UINT256 sig_n_prime256;
3372 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
3374 // NaN (CASE1)
3375 // if either number is NAN, the comparison is unordered,
3376 // rather than equal : return 0
3377 if (((x.w[1] & MASK_NAN) == MASK_NAN)
3378 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
3379 *pfpsf |= INVALID_EXCEPTION;
3381 res = 0;
3382 BID_RETURN (res);
3385 // SIMPLE (CASE2)
3386 // if all the bits are the same, these numbers are equal (not Greater).
3387 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
3388 res = 1;
3389 BID_RETURN (res);
3391 // INFINITY (CASE3)
3392 if ((x.w[1] & MASK_INF) == MASK_INF) {
3393 // if x is neg infinity, there is no way it is greater than y, return 1
3394 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
3395 res = 1;
3396 BID_RETURN (res);
3398 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity
3399 else {
3400 res = (((y.w[1] & MASK_INF) == MASK_INF)
3401 && ((y.w[1] & MASK_SIGN) != MASK_SIGN));
3402 BID_RETURN (res);
3404 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
3405 // x is finite, so if y is positive infinity, then x is less, return 0
3406 // if y is negative infinity, then x is greater, return 1
3408 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3409 BID_RETURN (res);
3412 // CONVERT X
3413 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
3414 sig_x.w[0] = x.w[0];
3415 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
3417 // CHECK IF X IS CANONICAL
3418 // 9999999999999999999999999999999999(decimal) =
3419 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3420 // [0, 10^34) is the 754r supported canonical range.
3421 // If the value exceeds that, it is interpreted as 0.
3422 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
3423 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
3424 && (sig_x.w[0] > 0x378d8e63ffffffffull))
3425 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3426 non_canon_x = 1;
3427 else
3428 non_canon_x = 0;
3430 // CONVERT Y
3431 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
3432 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
3433 sig_y.w[0] = y.w[0];
3435 // CHECK IF Y IS CANONICAL
3436 // 9999999999999999999999999999999999(decimal) =
3437 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3438 // [0, 10^34) is the 754r supported canonical range.
3439 // If the value exceeds that, it is interpreted as 0.
3440 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
3441 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
3442 && (sig_y.w[0] > 0x378d8e63ffffffffull))
3443 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3444 non_canon_y = 1;
3445 else
3446 non_canon_y = 0;
3448 // ZERO (CASE4)
3449 // some properties:
3450 // (+ZERO == -ZERO) => therefore ignore the sign
3451 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
3452 // ignore the exponent field
3453 // (Any non-canonical # is considered 0)
3454 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
3455 x_is_zero = 1;
3457 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
3458 y_is_zero = 1;
3460 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
3461 if (x_is_zero && y_is_zero) {
3462 res = 1;
3463 BID_RETURN (res);
3465 // is x is zero, it is greater if Y is negative
3466 else if (x_is_zero) {
3467 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3468 BID_RETURN (res);
3470 // is y is zero, X is greater if it is positive
3471 else if (y_is_zero) {
3472 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3473 BID_RETURN (res);
3475 // OPPOSITE SIGN (CASE5)
3476 // now, if the sign bits differ, x is greater if y is negative
3477 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
3478 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3479 BID_RETURN (res);
3481 // REDUNDANT REPRESENTATIONS (CASE6)
3482 // if exponents are the same, then we have a simple comparison
3483 // of the significands
3484 if (exp_y == exp_x) {
3485 res = (((sig_x.w[1] > sig_y.w[1])
3486 || (sig_x.w[1] == sig_y.w[1]
3487 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
3488 MASK_SIGN));
3489 BID_RETURN (res);
3491 // if both components are either bigger or smaller,
3492 // it is clear what needs to be done
3493 if ((sig_x.w[1] > sig_y.w[1]
3494 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
3495 && exp_x >= exp_y) {
3496 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3497 BID_RETURN (res);
3499 if ((sig_x.w[1] < sig_y.w[1]
3500 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
3501 && exp_x <= exp_y) {
3502 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3503 BID_RETURN (res);
3506 diff = exp_x - exp_y;
3508 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
3509 if (diff > 0) { // to simplify the loop below,
3511 // if exp_x is 33 greater than exp_y, no need for compensation
3512 if (diff > 33) {
3513 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3514 BID_RETURN (res);
3515 } // difference cannot be greater than 10^33
3517 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3518 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
3521 // if postitive, return whichever significand is larger
3522 // (converse if negative)
3523 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
3524 && sig_n_prime256.w[1] == sig_y.w[1]
3525 && (sig_n_prime256.w[0] == sig_y.w[0])) {
3526 res = 1;
3527 BID_RETURN (res);
3528 } // if equal, return 0
3530 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
3531 || (sig_n_prime256.w[1] > sig_y.w[1])
3532 || (sig_n_prime256.w[1] == sig_y.w[1]
3533 && sig_n_prime256.w[0] >
3534 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
3535 BID_RETURN (res);
3538 //else { //128 by 64 bit multiply -> 192 bits
3539 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
3541 // if postitive, return whichever significand is larger
3542 // (converse if negative)
3543 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
3544 && (sig_n_prime192.w[0] == sig_y.w[0])) {
3545 res = 1;
3546 BID_RETURN (res);
3547 } // if equal, return 0
3549 res = (((sig_n_prime192.w[2] > 0)
3550 || (sig_n_prime192.w[1] > sig_y.w[1])
3551 || (sig_n_prime192.w[1] == sig_y.w[1]
3552 && sig_n_prime192.w[0] >
3553 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
3554 BID_RETURN (res);
3558 diff = exp_y - exp_x;
3560 // if exp_x is 33 less than exp_y, no need for compensation
3561 if (diff > 33) {
3562 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3563 BID_RETURN (res);
3566 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3567 // adjust the y significand upwards
3568 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
3571 // if postitive, return whichever significand is larger
3572 // (converse if negative)
3573 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
3574 && sig_n_prime256.w[1] == sig_x.w[1]
3575 && (sig_n_prime256.w[0] == sig_x.w[0])) {
3576 res = 1;
3577 BID_RETURN (res);
3578 } // if equal, return 0
3580 res =
3581 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
3582 || (sig_n_prime256.w[1] > sig_x.w[1]
3583 || (sig_n_prime256.w[1] == sig_x.w[1]
3584 && sig_n_prime256.w[0] >
3585 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
3586 BID_RETURN (res);
3589 //else { //128 by 64 bit multiply -> 192 bits
3590 // adjust the y significand upwards
3591 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
3593 // if postitive, return whichever significand is larger
3594 // (converse if negative)
3595 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
3596 && (sig_n_prime192.w[0] == sig_x.w[0])) {
3597 res = 1;
3598 BID_RETURN (res);
3599 } // if equal, return 0
3601 res = (sig_n_prime192.w[2] != 0
3602 || (sig_n_prime192.w[1] > sig_x.w[1]
3603 || (sig_n_prime192.w[1] == sig_x.w[1]
3604 && sig_n_prime192.w[0] >
3605 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
3606 BID_RETURN (res);
3610 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
3611 bid128_signaling_less_unordered,
3612 x, y)
3614 int res;
3615 int exp_x, exp_y;
3616 int diff;
3617 UINT128 sig_x, sig_y;
3618 UINT192 sig_n_prime192;
3619 UINT256 sig_n_prime256;
3620 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
3622 // NaN (CASE1)
3623 // if either number is NAN, the comparison is unordered
3624 if (((x.w[1] & MASK_NAN) == MASK_NAN)
3625 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
3626 *pfpsf |= INVALID_EXCEPTION;
3628 res = 1;
3629 BID_RETURN (res);
3632 // SIMPLE (CASE2)
3633 // if all the bits are the same, these numbers are equal.
3634 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
3635 res = 0;
3636 BID_RETURN (res);
3638 // INFINITY (CASE3)
3639 if ((x.w[1] & MASK_INF) == MASK_INF) {
3640 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
3641 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
3642 // x is -inf, so it is less than y unless y is -inf
3644 res = (((y.w[1] & MASK_INF) != MASK_INF)
3645 || (y.w[1] & MASK_SIGN) != MASK_SIGN);
3646 BID_RETURN (res);
3647 } else
3648 // x is pos_inf, no way for it to be less than y
3650 res = 0;
3651 BID_RETURN (res);
3653 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
3654 // x is finite, so if y is positive infinity, then x is less, return 0
3655 // if y is negative infinity, then x is greater, return 1
3657 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3658 BID_RETURN (res);
3661 // CONVERT X
3662 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
3663 sig_x.w[0] = x.w[0];
3664 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
3666 // CHECK IF X IS CANONICAL
3667 // 9999999999999999999999999999999999(decimal) =
3668 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3669 // [0, 10^34) is the 754r supported canonical range.
3670 // If the value exceeds that, it is interpreted as 0.
3671 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
3672 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
3673 && (sig_x.w[0] > 0x378d8e63ffffffffull))
3674 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3675 non_canon_x = 1;
3676 else
3677 non_canon_x = 0;
3679 // CONVERT Y
3680 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
3681 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
3682 sig_y.w[0] = y.w[0];
3684 // CHECK IF Y IS CANONICAL
3685 // 9999999999999999999999999999999999(decimal) =
3686 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3687 // [0, 10^34) is the 754r supported canonical range.
3688 // If the value exceeds that, it is interpreted as 0.
3689 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
3690 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
3691 && (sig_y.w[0] > 0x378d8e63ffffffffull))
3692 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3693 non_canon_y = 1;
3694 else
3695 non_canon_y = 0;
3697 // ZERO (CASE4)
3698 // some properties:
3699 // (+ZERO == -ZERO) => therefore ignore the sign
3700 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
3701 // ignore the exponent field
3702 // (Any non-canonical # is considered 0)
3703 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
3704 x_is_zero = 1;
3706 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
3707 y_is_zero = 1;
3709 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
3710 if (x_is_zero && y_is_zero) {
3711 res = 0;
3712 BID_RETURN (res);
3714 // is x is zero, it is greater if Y is negative
3715 else if (x_is_zero) {
3716 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3717 BID_RETURN (res);
3719 // is y is zero, X is greater if it is positive
3720 else if (y_is_zero) {
3721 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3722 BID_RETURN (res);
3724 // OPPOSITE SIGN (CASE5)
3725 // now, if the sign bits differ, x is greater if y is negative
3726 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
3727 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3728 BID_RETURN (res);
3730 // REDUNDANT REPRESENTATIONS (CASE6)
3731 // if exponents are the same, then we have a simple comparison
3732 // of the significands
3733 if (exp_y == exp_x) {
3734 res = (((sig_x.w[1] > sig_y.w[1])
3735 || (sig_x.w[1] == sig_y.w[1]
3736 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
3737 MASK_SIGN));
3738 BID_RETURN (res);
3740 // if both components are either bigger or smaller,
3741 // it is clear what needs to be done
3742 if ((sig_x.w[1] > sig_y.w[1]
3743 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
3744 && exp_x >= exp_y) {
3745 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3746 BID_RETURN (res);
3748 if ((sig_x.w[1] < sig_y.w[1]
3749 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
3750 && exp_x <= exp_y) {
3751 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3752 BID_RETURN (res);
3755 diff = exp_x - exp_y;
3757 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
3758 if (diff > 0) { // to simplify the loop below,
3760 // if exp_x is 33 greater than exp_y, no need for compensation
3761 if (diff > 33) {
3762 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3763 BID_RETURN (res);
3764 } // difference cannot be greater than 10^33
3766 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3767 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
3770 // if postitive, return whichever significand is larger
3771 // (converse if negative)
3772 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
3773 && sig_n_prime256.w[1] == sig_y.w[1]
3774 && (sig_n_prime256.w[0] == sig_y.w[0])) {
3775 res = 0;
3776 BID_RETURN (res);
3777 } // if equal, return 0
3779 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
3780 || (sig_n_prime256.w[1] > sig_y.w[1])
3781 || (sig_n_prime256.w[1] == sig_y.w[1]
3782 && sig_n_prime256.w[0] >
3783 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
3784 BID_RETURN (res);
3787 //else { //128 by 64 bit multiply -> 192 bits
3788 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
3790 // if postitive, return whichever significand is larger
3791 // (converse if negative)
3792 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
3793 && (sig_n_prime192.w[0] == sig_y.w[0])) {
3794 res = 0;
3795 BID_RETURN (res);
3796 } // if equal, return 0
3798 res = (((sig_n_prime192.w[2] > 0)
3799 || (sig_n_prime192.w[1] > sig_y.w[1])
3800 || (sig_n_prime192.w[1] == sig_y.w[1]
3801 && sig_n_prime192.w[0] >
3802 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
3803 BID_RETURN (res);
3807 diff = exp_y - exp_x;
3809 // if exp_x is 33 less than exp_y, no need for compensation
3810 if (diff > 33) {
3811 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3812 BID_RETURN (res);
3815 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
3816 // adjust the y significand upwards
3817 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
3820 // if postitive, return whichever significand is larger
3821 // (converse if negative)
3822 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
3823 && sig_n_prime256.w[1] == sig_x.w[1]
3824 && (sig_n_prime256.w[0] == sig_x.w[0])) {
3825 res = 0;
3826 BID_RETURN (res);
3827 } // if equal, return 1
3829 res =
3830 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
3831 || (sig_n_prime256.w[1] > sig_x.w[1]
3832 || (sig_n_prime256.w[1] == sig_x.w[1]
3833 && sig_n_prime256.w[0] >
3834 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
3835 BID_RETURN (res);
3838 //else { //128 by 64 bit multiply -> 192 bits
3839 // adjust the y significand upwards
3840 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
3842 // if postitive, return whichever significand is larger (converse if negative)
3843 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
3844 && (sig_n_prime192.w[0] == sig_x.w[0])) {
3845 res = 0;
3846 BID_RETURN (res);
3847 } // if equal, return 0
3849 res = (sig_n_prime192.w[2] != 0
3850 || (sig_n_prime192.w[1] > sig_x.w[1]
3851 || (sig_n_prime192.w[1] == sig_x.w[1]
3852 && sig_n_prime192.w[0] >
3853 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
3854 BID_RETURN (res);
3858 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
3859 bid128_signaling_not_greater,
3860 x, y)
3862 int res;
3863 int exp_x, exp_y;
3864 int diff;
3865 UINT128 sig_x, sig_y;
3866 UINT192 sig_n_prime192;
3867 UINT256 sig_n_prime256;
3868 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
3870 // NaN (CASE1)
3871 // if either number is NAN, the comparison is unordered,
3872 // rather than equal : return 0
3873 if (((x.w[1] & MASK_NAN) == MASK_NAN)
3874 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
3875 *pfpsf |= INVALID_EXCEPTION;
3877 res = 1;
3878 BID_RETURN (res);
3881 // SIMPLE (CASE2)
3882 // if all the bits are the same, these numbers are equal (not Greater).
3883 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
3884 res = 1;
3885 BID_RETURN (res);
3887 // INFINITY (CASE3)
3888 if ((x.w[1] & MASK_INF) == MASK_INF) {
3889 // if x is neg infinity, there is no way it is greater than y, return 1
3890 if (((x.w[1] & MASK_SIGN) == MASK_SIGN)) {
3891 res = 1;
3892 BID_RETURN (res);
3894 // x is pos infinity, it is greater, unless y is positive infinity => return y!=pos_infinity
3895 else {
3896 res = (((y.w[1] & MASK_INF) == MASK_INF)
3897 && ((y.w[1] & MASK_SIGN) != MASK_SIGN));
3898 BID_RETURN (res);
3900 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
3901 // x is finite, so if y is positive infinity, then x is less, return 0
3902 // if y is negative infinity, then x is greater, return 1
3904 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3905 BID_RETURN (res);
3908 // CONVERT X
3909 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
3910 sig_x.w[0] = x.w[0];
3911 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
3913 // CHECK IF X IS CANONICAL
3914 // 9999999999999999999999999999999999(decimal) =
3915 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3916 // [0, 10^34) is the 754r supported canonical range.
3917 // If the value exceeds that, it is interpreted as 0.
3918 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
3919 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
3920 && (sig_x.w[0] > 0x378d8e63ffffffffull))
3921 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3922 non_canon_x = 1;
3923 else
3924 non_canon_x = 0;
3926 // CONVERT Y
3927 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
3928 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
3929 sig_y.w[0] = y.w[0];
3931 // CHECK IF Y IS CANONICAL
3932 // 9999999999999999999999999999999999(decimal) =
3933 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
3934 // [0, 10^34) is the 754r supported canonical range.
3935 // If the value exceeds that, it is interpreted as 0.
3936 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
3937 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
3938 && (sig_y.w[0] > 0x378d8e63ffffffffull))
3939 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
3940 non_canon_y = 1;
3941 else
3942 non_canon_y = 0;
3944 // ZERO (CASE4)
3945 // some properties:
3946 // (+ZERO == -ZERO) => therefore ignore the sign
3947 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
3948 // ignore the exponent field
3949 // (Any non-canonical # is considered 0)
3950 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
3951 x_is_zero = 1;
3953 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
3954 y_is_zero = 1;
3956 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
3957 if (x_is_zero && y_is_zero) {
3958 res = 1;
3959 BID_RETURN (res);
3961 // is x is zero, it is greater if Y is negative
3962 else if (x_is_zero) {
3963 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3964 BID_RETURN (res);
3966 // is y is zero, X is greater if it is positive
3967 else if (y_is_zero) {
3968 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3969 BID_RETURN (res);
3971 // OPPOSITE SIGN (CASE5)
3972 // now, if the sign bits differ, x is greater if y is negative
3973 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
3974 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
3975 BID_RETURN (res);
3977 // REDUNDANT REPRESENTATIONS (CASE6)
3978 // if exponents are the same, then we have a simple comparison
3979 // of the significands
3980 if (exp_y == exp_x) {
3981 res = (((sig_x.w[1] > sig_y.w[1])
3982 || (sig_x.w[1] == sig_y.w[1]
3983 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) !=
3984 MASK_SIGN));
3985 BID_RETURN (res);
3987 // if both components are either bigger or smaller,
3988 // it is clear what needs to be done
3989 if ((sig_x.w[1] > sig_y.w[1]
3990 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
3991 && exp_x >= exp_y) {
3992 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
3993 BID_RETURN (res);
3995 if ((sig_x.w[1] < sig_y.w[1]
3996 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
3997 && exp_x <= exp_y) {
3998 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
3999 BID_RETURN (res);
4002 diff = exp_x - exp_y;
4004 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
4005 if (diff > 0) { // to simplify the loop below,
4007 // if exp_x is 33 greater than exp_y, no need for compensation
4008 if (diff > 33) {
4009 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
4010 BID_RETURN (res);
4011 } // difference cannot be greater than 10^33
4013 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
4014 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
4017 // if postitive, return whichever significand is larger
4018 // (converse if negative)
4019 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
4020 && sig_n_prime256.w[1] == sig_y.w[1]
4021 && (sig_n_prime256.w[0] == sig_y.w[0])) {
4022 res = 1;
4023 BID_RETURN (res);
4024 } // if equal, return 0
4026 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
4027 || (sig_n_prime256.w[1] > sig_y.w[1])
4028 || (sig_n_prime256.w[1] == sig_y.w[1]
4029 && sig_n_prime256.w[0] >
4030 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
4031 BID_RETURN (res);
4034 //else { //128 by 64 bit multiply -> 192 bits
4035 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
4037 // if postitive, return whichever significand is larger
4038 // (converse if negative)
4039 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
4040 && (sig_n_prime192.w[0] == sig_y.w[0])) {
4041 res = 1;
4042 BID_RETURN (res);
4043 } // if equal, return 0
4045 res = (((sig_n_prime192.w[2] > 0)
4046 || (sig_n_prime192.w[1] > sig_y.w[1])
4047 || (sig_n_prime192.w[1] == sig_y.w[1]
4048 && sig_n_prime192.w[0] >
4049 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) != MASK_SIGN));
4050 BID_RETURN (res);
4054 diff = exp_y - exp_x;
4056 // if exp_x is 33 less than exp_y, no need for compensation
4057 if (diff > 33) {
4058 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
4059 BID_RETURN (res);
4062 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
4063 // adjust the y significand upwards
4064 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
4066 // if postitive, return whichever significand is larger
4067 // (converse if negative)
4068 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
4069 && sig_n_prime256.w[1] == sig_x.w[1]
4070 && (sig_n_prime256.w[0] == sig_x.w[0])) {
4071 res = 1;
4072 BID_RETURN (res);
4073 } // if equal, return 0
4075 res =
4076 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
4077 || (sig_n_prime256.w[1] > sig_x.w[1]
4078 || (sig_n_prime256.w[1] == sig_x.w[1]
4079 && sig_n_prime256.w[0] >
4080 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
4081 BID_RETURN (res);
4084 //else { //128 by 64 bit multiply -> 192 bits
4085 // adjust the y significand upwards
4086 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
4088 // if postitive, return whichever significand is larger
4089 // (converse if negative)
4090 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
4091 && (sig_n_prime192.w[0] == sig_x.w[0])) {
4092 res = 1;
4093 BID_RETURN (res);
4094 } // if equal, return 0
4096 res = (sig_n_prime192.w[2] != 0
4097 || (sig_n_prime192.w[1] > sig_x.w[1]
4098 || (sig_n_prime192.w[1] == sig_x.w[1]
4099 && sig_n_prime192.w[0] >
4100 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
4101 BID_RETURN (res);
4105 BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (int,
4106 bid128_signaling_not_less, x,
4109 int res;
4110 int exp_x, exp_y;
4111 int diff;
4112 UINT128 sig_x, sig_y;
4113 UINT192 sig_n_prime192;
4114 UINT256 sig_n_prime256;
4115 char x_is_zero = 0, y_is_zero = 0, non_canon_x, non_canon_y;
4117 // NaN (CASE1)
4118 // if either number is NAN, the comparison is unordered,
4119 // rather than equal : return 1
4120 if (((x.w[1] & MASK_NAN) == MASK_NAN)
4121 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
4122 *pfpsf |= INVALID_EXCEPTION;
4124 res = 1;
4125 BID_RETURN (res);
4128 // SIMPLE (CASE2)
4129 // if all the bits are the same, these numbers are equal (not Greater).
4130 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
4131 res = 1;
4132 BID_RETURN (res);
4134 // INFINITY (CASE3)
4135 if ((x.w[1] & MASK_INF) == MASK_INF) {
4136 // if x==neg_inf, { res = (y == neg_inf)?1:0; BID_RETURN (res) }
4137 if ((x.w[1] & MASK_SIGN) == MASK_SIGN)
4138 // x is -inf, so it is less than y unless y is -inf
4140 res = (((y.w[1] & MASK_INF) == MASK_INF)
4141 && (y.w[1] & MASK_SIGN) == MASK_SIGN);
4142 BID_RETURN (res);
4143 } else
4144 // x is pos_inf, no way for it to be less than y
4146 res = 1;
4147 BID_RETURN (res);
4149 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
4150 // x is finite, so if y is positive infinity, then x is less, return 0
4151 // if y is negative infinity, then x is greater, return 1
4153 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
4154 BID_RETURN (res);
4157 // CONVERT X
4158 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
4159 sig_x.w[0] = x.w[0];
4160 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
4162 // CHECK IF X IS CANONICAL
4163 // 9999999999999999999999999999999999(decimal) =
4164 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
4165 // [0, 10^34) is the 754r supported canonical range.
4166 // If the value exceeds that, it is interpreted as 0.
4167 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
4168 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
4169 && (sig_x.w[0] > 0x378d8e63ffffffffull))
4170 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
4171 non_canon_x = 1;
4172 else
4173 non_canon_x = 0;
4175 // CONVERT Y
4176 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
4177 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
4178 sig_y.w[0] = y.w[0];
4180 // CHECK IF Y IS CANONICAL
4181 // 9999999999999999999999999999999999(decimal) =
4182 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
4183 // [0, 10^34) is the 754r supported canonical range.
4184 // If the value exceeds that, it is interpreted as 0.
4185 if ((sig_y.w[1] > 0x0001ed09bead87c0ull)
4186 || ((sig_y.w[1] == 0x0001ed09bead87c0ull)
4187 && (sig_y.w[0] > 0x378d8e63ffffffffull))
4188 || ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull))
4189 non_canon_y = 1;
4190 else
4191 non_canon_y = 0;
4193 // ZERO (CASE4)
4194 // some properties:
4195 // (+ZERO == -ZERO) => therefore ignore the sign
4196 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore
4197 // ignore the exponent field
4198 // (Any non-canonical # is considered 0)
4199 if (non_canon_x || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
4200 x_is_zero = 1;
4202 if (non_canon_y || ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
4203 y_is_zero = 1;
4205 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
4206 if (x_is_zero && y_is_zero) {
4207 res = 1;
4208 BID_RETURN (res);
4210 // is x is zero, it is greater if Y is negative
4211 else if (x_is_zero) {
4212 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
4213 BID_RETURN (res);
4215 // is y is zero, X is greater if it is positive
4216 else if (y_is_zero) {
4217 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
4218 BID_RETURN (res);
4220 // OPPOSITE SIGN (CASE5)
4221 // now, if the sign bits differ, x is greater if y is negative
4222 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
4223 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN);
4224 BID_RETURN (res);
4226 // REDUNDANT REPRESENTATIONS (CASE6)
4228 // if exponents are the same, then we have a simple comparison
4229 // of the significands
4230 if (exp_y == exp_x) {
4231 res = (((sig_x.w[1] > sig_y.w[1])
4232 || (sig_x.w[1] == sig_y.w[1]
4233 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
4234 MASK_SIGN));
4235 BID_RETURN (res);
4237 // if both components are either bigger or smaller,
4238 // it is clear what needs to be done
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);
4244 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
4245 && exp_x < exp_y) {
4246 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
4247 BID_RETURN (res);
4250 diff = exp_x - exp_y;
4252 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
4253 if (diff > 0) { // to simplify the loop below,
4255 // if exp_x is 33 greater than exp_y, no need for compensation
4256 if (diff > 33) {
4257 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
4258 BID_RETURN (res);
4259 } // difference cannot be greater than 10^33
4261 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
4262 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
4265 // if postitive, return whichever significand is larger
4266 // (converse if negative)
4267 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
4268 && sig_n_prime256.w[1] == sig_y.w[1]
4269 && (sig_n_prime256.w[0] == sig_y.w[0])) {
4270 res = 1;
4271 BID_RETURN (res);
4272 } // if equal, return 1
4274 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
4275 || (sig_n_prime256.w[1] > sig_y.w[1])
4276 || (sig_n_prime256.w[1] == sig_y.w[1]
4277 && sig_n_prime256.w[0] >
4278 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
4279 BID_RETURN (res);
4282 //else { //128 by 64 bit multiply -> 192 bits
4283 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_x);
4285 // if postitive, return whichever significand is larger
4286 // (converse if negative)
4287 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
4288 && (sig_n_prime192.w[0] == sig_y.w[0])) {
4289 res = 1;
4290 BID_RETURN (res);
4291 } // if equal, return 1
4293 res = (((sig_n_prime192.w[2] > 0)
4294 || (sig_n_prime192.w[1] > sig_y.w[1])
4295 || (sig_n_prime192.w[1] == sig_y.w[1]
4296 && sig_n_prime192.w[0] >
4297 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN));
4298 BID_RETURN (res);
4302 diff = exp_y - exp_x;
4304 // if exp_x is 33 less than exp_y, no need for compensation
4305 if (diff > 33) {
4306 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
4307 BID_RETURN (res);
4310 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
4311 // adjust the y significand upwards
4312 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
4315 // if postitive, return whichever significand is larger
4316 // (converse if negative)
4317 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
4318 && sig_n_prime256.w[1] == sig_x.w[1]
4319 && (sig_n_prime256.w[0] == sig_x.w[0])) {
4320 res = 1;
4321 BID_RETURN (res);
4322 } // if equal, return 1
4324 res =
4325 ((sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
4326 && (sig_n_prime256.w[1] < sig_x.w[1]
4327 || (sig_n_prime256.w[1] == sig_x.w[1]
4328 && sig_n_prime256.w[0] <
4329 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
4330 BID_RETURN (res);
4333 //else { //128 by 64 bit multiply -> 192 bits
4334 // adjust the y significand upwards
4335 __mul_64x128_to192 (sig_n_prime192, ten2k64[diff], sig_y);
4337 // if postitive, return whichever significand is larger (converse if negative)
4338 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
4339 && (sig_n_prime192.w[0] == sig_x.w[0])) {
4340 res = 1;
4341 BID_RETURN (res);
4342 } // if equal, return 1
4344 res = (sig_n_prime192.w[2] == 0
4345 && (sig_n_prime192.w[1] < sig_x.w[1]
4346 || (sig_n_prime192.w[1] == sig_x.w[1]
4347 && sig_n_prime192.w[0] <
4348 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN);
4349 BID_RETURN (res);