]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/libbid/bid128_noncomp.c
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / libbid / bid128_noncomp.c
CommitLineData
a945c346 1/* Copyright (C) 2007-2024 Free Software Foundation, Inc.
200359e8
L
2
3This file is part of GCC.
4
5GCC is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License as published by the Free
748086b7 7Software Foundation; either version 3, or (at your option) any later
200359e8
L
8version.
9
200359e8
L
10GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11WARRANTY; without even the implied warranty of MERCHANTABILITY or
12FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13for more details.
14
748086b7
JJ
15Under Section 7 of GPL version 3, you are granted additional
16permissions described in the GCC Runtime Library Exception, version
173.1, as published by the Free Software Foundation.
18
19You should have received a copy of the GNU General Public License and
20a copy of the GCC Runtime Library Exception along with this program;
21see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22<http://www.gnu.org/licenses/>. */
200359e8
L
23
24#include "bid_internal.h"
25
26/*****************************************************************************
27 *
28 * BID128 non-computational functions:
b2a00c89
L
29 * - bid128_isSigned
30 * - bid128_isNormal
31 * - bid128_isSubnormal
32 * - bid128_isFinite
33 * - bid128_isZero
34 * - bid128_isInf
35 * - bid128_isSignaling
36 * - bid128_isCanonical
37 * - bid128_isNaN
38 * - bid128_copy
39 * - bid128_negate
40 * - bid128_abs
41 * - bid128_copySign
42 * - bid128_class
43 * - bid128_totalOrder
44 * - bid128_totalOrderMag
45 * - bid128_sameQuantum
46 * - bid128_radix
200359e8
L
47 ****************************************************************************/
48
49#if DECIMAL_CALL_BY_REFERENCE
50void
b2a00c89
L
51bid128_isSigned (int *pres,
52 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
53 UINT128 x = *px;
54#else
55int
b2a00c89 56bid128_isSigned (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
57#endif
58 int res;
59
60 res = ((x.w[HIGH_128W] & MASK_SIGN) == MASK_SIGN);
61 BID_RETURN (res);
62}
63
64// return 1 iff x is not zero, nor NaN nor subnormal nor infinity
65#if DECIMAL_CALL_BY_REFERENCE
66void
b2a00c89
L
67bid128_isNormal (int *pres,
68 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
69 UINT128 x = *px;
70#else
71int
b2a00c89 72bid128_isNormal (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
73#endif
74 int res;
75 UINT64 x_exp, C1_hi, C1_lo;
76 BID_UI64DOUBLE tmp1;
77 int exp, q, x_nr_bits;
78
b2a00c89 79 BID_SWAP128 (x);
200359e8
L
80 // test for special values - infinity or NaN
81 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
82 // x is special
83 res = 0;
84 BID_RETURN (res);
85 }
86 // unpack x
b2a00c89 87 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
200359e8
L
88 C1_hi = x.w[1] & MASK_COEFF;
89 C1_lo = x.w[0];
90 // test for zero
91 if (C1_hi == 0 && C1_lo == 0) {
92 res = 0;
93 BID_RETURN (res);
94 }
95 // test for non-canonical values of the argument x
96 if ((((C1_hi > 0x0001ed09bead87c0ull)
b2a00c89
L
97 || ((C1_hi == 0x0001ed09bead87c0ull)
98 && (C1_lo > 0x378d8e63ffffffffull)))
99 && ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull))
200359e8
L
100 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
101 res = 0;
102 BID_RETURN (res);
103 }
104 // x is subnormal or normal
105 // determine the number of digits q in the significand
106 // q = nr. of decimal digits in x
107 // determine first the nr. of bits in x
108 if (C1_hi == 0) {
b2a00c89 109 if (C1_lo >= 0x0020000000000000ull) { // x >= 2^53
200359e8 110 // split the 64-bit value in two 32-bit halves to avoid rounding errors
b2a00c89
L
111 if (C1_lo >= 0x0000000100000000ull) { // x >= 2^32
112 tmp1.d = (double) (C1_lo >> 32); // exact conversion
113 x_nr_bits =
114 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
115 } else { // x < 2^32
116 tmp1.d = (double) (C1_lo); // exact conversion
117 x_nr_bits =
118 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
200359e8 119 }
b2a00c89
L
120 } else { // if x < 2^53
121 tmp1.d = (double) C1_lo; // exact conversion
200359e8 122 x_nr_bits =
b2a00c89 123 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
200359e8 124 }
b2a00c89
L
125 } else { // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi)
126 tmp1.d = (double) C1_hi; // exact conversion
200359e8
L
127 x_nr_bits =
128 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
129 }
b2a00c89 130 q = nr_digits[x_nr_bits - 1].digits;
200359e8 131 if (q == 0) {
b2a00c89
L
132 q = nr_digits[x_nr_bits - 1].digits1;
133 if (C1_hi > nr_digits[x_nr_bits - 1].threshold_hi ||
134 (C1_hi == nr_digits[x_nr_bits - 1].threshold_hi &&
135 C1_lo >= nr_digits[x_nr_bits - 1].threshold_lo))
200359e8
L
136 q++;
137 }
138 exp = (int) (x_exp >> 49) - 6176;
139 // test for subnormal values of x
140 if (exp + q <= -6143) {
141 res = 0;
142 BID_RETURN (res);
143 } else {
144 res = 1;
145 BID_RETURN (res);
146 }
147}
148
149// return 1 iff x is not zero, nor NaN nor normal nor infinity
150#if DECIMAL_CALL_BY_REFERENCE
151void
b2a00c89
L
152bid128_isSubnormal (int *pres,
153 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
154 UINT128 x = *px;
155#else
156int
b2a00c89 157bid128_isSubnormal (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
158#endif
159 int res;
160 UINT64 x_exp, C1_hi, C1_lo;
161 BID_UI64DOUBLE tmp1;
162 int exp, q, x_nr_bits;
163
b2a00c89 164 BID_SWAP128 (x);
200359e8
L
165 // test for special values - infinity or NaN
166 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
167 // x is special
168 res = 0;
169 BID_RETURN (res);
170 }
171 // unpack x
b2a00c89 172 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
200359e8
L
173 C1_hi = x.w[1] & MASK_COEFF;
174 C1_lo = x.w[0];
175 // test for zero
176 if (C1_hi == 0 && C1_lo == 0) {
177 res = 0;
178 BID_RETURN (res);
179 }
180 // test for non-canonical values of the argument x
181 if ((((C1_hi > 0x0001ed09bead87c0ull)
b2a00c89
L
182 || ((C1_hi == 0x0001ed09bead87c0ull)
183 && (C1_lo > 0x378d8e63ffffffffull)))
184 && ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull))
200359e8
L
185 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
186 res = 0;
187 BID_RETURN (res);
188 }
189 // x is subnormal or normal
190 // determine the number of digits q in the significand
191 // q = nr. of decimal digits in x
192 // determine first the nr. of bits in x
193 if (C1_hi == 0) {
b2a00c89 194 if (C1_lo >= 0x0020000000000000ull) { // x >= 2^53
200359e8 195 // split the 64-bit value in two 32-bit halves to avoid rounding errors
b2a00c89
L
196 if (C1_lo >= 0x0000000100000000ull) { // x >= 2^32
197 tmp1.d = (double) (C1_lo >> 32); // exact conversion
198 x_nr_bits =
199 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
200 } else { // x < 2^32
201 tmp1.d = (double) (C1_lo); // exact conversion
202 x_nr_bits =
203 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
200359e8 204 }
b2a00c89
L
205 } else { // if x < 2^53
206 tmp1.d = (double) C1_lo; // exact conversion
200359e8 207 x_nr_bits =
b2a00c89 208 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
200359e8 209 }
b2a00c89
L
210 } else { // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi)
211 tmp1.d = (double) C1_hi; // exact conversion
200359e8
L
212 x_nr_bits =
213 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
214 }
b2a00c89 215 q = nr_digits[x_nr_bits - 1].digits;
200359e8 216 if (q == 0) {
b2a00c89
L
217 q = nr_digits[x_nr_bits - 1].digits1;
218 if (C1_hi > nr_digits[x_nr_bits - 1].threshold_hi ||
219 (C1_hi == nr_digits[x_nr_bits - 1].threshold_hi &&
220 C1_lo >= nr_digits[x_nr_bits - 1].threshold_lo))
200359e8
L
221 q++;
222 }
223 exp = (int) (x_exp >> 49) - 6176;
224 // test for subnormal values of x
225 if (exp + q <= -6143) {
226 res = 1;
227 } else {
228 res = 0;
229 }
230 BID_RETURN (res);
231}
232
233#if DECIMAL_CALL_BY_REFERENCE
234void
b2a00c89
L
235bid128_isFinite (int *pres,
236 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
237 UINT128 x = *px;
238#else
239int
b2a00c89 240bid128_isFinite (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
241#endif
242 int res;
243 res = ((x.w[HIGH_128W] & MASK_INF) != MASK_INF);
244 BID_RETURN (res);
245}
246
247#if DECIMAL_CALL_BY_REFERENCE
248void
b2a00c89 249bid128_isZero (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
250 UINT128 x = *px;
251#else
252int
b2a00c89 253bid128_isZero (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
254#endif
255 int res;
256 UINT128 sig_x;
257
b2a00c89 258 BID_SWAP128 (x);
200359e8
L
259 if ((x.w[1] & MASK_INF) == MASK_INF) {
260 res = 0;
261 BID_RETURN (res);
262 }
263 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
264 sig_x.w[0] = x.w[0];
b2a00c89
L
265 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) || // significand is non-canonical
266 ((sig_x.w[1] == 0x0001ed09bead87c0ull) && (sig_x.w[0] > 0x378d8e63ffffffffull)) || // significand is non-canonical
267 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull && (x.w[1] & MASK_INF) != MASK_INF) || // significand is non-canonical
268 (sig_x.w[1] == 0 && sig_x.w[0] == 0)) { // significand is 0
200359e8
L
269 res = 1;
270 BID_RETURN (res);
271 }
272 res = 0;
273 BID_RETURN (res);
274}
275
276#if DECIMAL_CALL_BY_REFERENCE
277void
b2a00c89 278bid128_isInf (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
279 UINT128 x = *px;
280#else
281int
b2a00c89 282bid128_isInf (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
283#endif
284 int res;
285 res = ((x.w[HIGH_128W] & MASK_INF) == MASK_INF)
286 && ((x.w[HIGH_128W] & MASK_NAN) != MASK_NAN);
287 BID_RETURN (res);
288}
289
290#if DECIMAL_CALL_BY_REFERENCE
291void
b2a00c89
L
292bid128_isSignaling (int *pres,
293 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
294 UINT128 x = *px;
295#else
296int
b2a00c89 297bid128_isSignaling (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
298#endif
299 int res;
300
301 res = ((x.w[HIGH_128W] & MASK_SNAN) == MASK_SNAN);
302 BID_RETURN (res);
303}
304
305// return 1 iff x is a canonical number ,infinity, or NaN.
306#if DECIMAL_CALL_BY_REFERENCE
307void
b2a00c89
L
308bid128_isCanonical (int *pres,
309 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
310 UINT128 x = *px;
311#else
312int
b2a00c89 313bid128_isCanonical (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
314#endif
315 int res;
316 UINT128 sig_x;
317
b2a00c89
L
318 BID_SWAP128 (x);
319 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // NaN
200359e8
L
320 if (x.w[1] & 0x01ffc00000000000ull) {
321 res = 0;
322 BID_RETURN (res);
323 }
b2a00c89
L
324 sig_x.w[1] = x.w[1] & 0x00003fffffffffffull; // 46 bits
325 sig_x.w[0] = x.w[0]; // 64 bits
200359e8
L
326 // payload must be < 10^33 = 0x0000314dc6448d93_38c15b0a00000000
327 if (sig_x.w[1] < 0x0000314dc6448d93ull
b2a00c89
L
328 || (sig_x.w[1] == 0x0000314dc6448d93ull
329 && sig_x.w[0] < 0x38c15b0a00000000ull)) {
200359e8
L
330 res = 1;
331 } else {
332 res = 0;
333 }
334 BID_RETURN (res);
b2a00c89 335 } else if ((x.w[1] & MASK_INF) == MASK_INF) { // infinity
200359e8
L
336 if ((x.w[1] & 0x03ffffffffffffffull) || x.w[0]) {
337 res = 0;
338 } else {
339 res = 1;
340 }
341 BID_RETURN (res);
342 }
343 // not NaN or infinity; extract significand to ensure it is canonical
344 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
345 sig_x.w[0] = x.w[0];
346 // a canonical number has a coefficient < 10^34
347 // (0x0001ed09_bead87c0_378d8e64_00000000)
b2a00c89
L
348 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) || // significand is non-canonical
349 ((sig_x.w[1] == 0x0001ed09bead87c0ull) && (sig_x.w[0] > 0x378d8e63ffffffffull)) || // significand is non-canonical
200359e8
L
350 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
351 res = 0;
352 } else {
353 res = 1;
354 }
355 BID_RETURN (res);
356}
357
358#if DECIMAL_CALL_BY_REFERENCE
359void
b2a00c89 360bid128_isNaN (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
361 UINT128 x = *px;
362#else
363int
b2a00c89 364bid128_isNaN (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
365#endif
366 int res;
367
368 res = ((x.w[HIGH_128W] & MASK_NAN) == MASK_NAN);
369 BID_RETURN (res);
370}
371
372// copies a floating-point operand x to destination y, with no change
373#if DECIMAL_CALL_BY_REFERENCE
374void
b2a00c89
L
375bid128_copy (UINT128 * pres,
376 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
377 UINT128 x = *px;
378#else
379UINT128
b2a00c89 380bid128_copy (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
381#endif
382 UINT128 res;
383
384 res = x;
385 BID_RETURN (res);
386}
387
388// copies a floating-point operand x to destination y, reversing the sign
389#if DECIMAL_CALL_BY_REFERENCE
390void
b2a00c89
L
391bid128_negate (UINT128 * pres,
392 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
393 UINT128 x = *px;
394#else
395UINT128
b2a00c89 396bid128_negate (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
397#endif
398 UINT128 res;
399
400 x.w[HIGH_128W] ^= MASK_SIGN;
401 res = x;
402 BID_RETURN (res);
403}
404
405// copies a floating-point operand x to destination y, changing the sign to positive
406#if DECIMAL_CALL_BY_REFERENCE
407void
b2a00c89
L
408bid128_abs (UINT128 * pres,
409 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
410 UINT128 x = *px;
411#else
412UINT128
b2a00c89 413bid128_abs (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
414#endif
415 UINT128 res;
416
417 x.w[HIGH_128W] &= ~MASK_SIGN;
418 res = x;
419 BID_RETURN (res);
420}
421
422// copies operand x to destination in the same format as x, but with the sign of y
423#if DECIMAL_CALL_BY_REFERENCE
424void
b2a00c89
L
425bid128_copySign (UINT128 * pres, UINT128 * px,
426 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
427 UINT128 x = *px;
428 UINT128 y = *py;
429#else
430UINT128
b2a00c89 431bid128_copySign (UINT128 x, UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
432#endif
433 UINT128 res;
434
b2a00c89
L
435 x.w[HIGH_128W] =
436 (x.w[HIGH_128W] & ~MASK_SIGN) | (y.w[HIGH_128W] & MASK_SIGN);
200359e8
L
437 res = x;
438 BID_RETURN (res);
439}
440
441#if DECIMAL_CALL_BY_REFERENCE
442void
b2a00c89 443bid128_class (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
444 UINT128 x = *px;
445#else
446int
b2a00c89 447bid128_class (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
448#endif
449 int res;
450 UINT256 sig_x_prime256;
451 UINT192 sig_x_prime192;
452 UINT128 sig_x;
453 int exp_x;
454
b2a00c89 455 BID_SWAP128 (x);
200359e8
L
456 if ((x.w[1] & MASK_NAN) == MASK_NAN) {
457 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {
458 res = signalingNaN;
459 } else {
460 res = quietNaN;
461 }
462 BID_RETURN (res);
463 }
464 if ((x.w[1] & MASK_INF) == MASK_INF) {
465 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
466 res = negativeInfinity;
467 } else {
468 res = positiveInfinity;
469 }
470 BID_RETURN (res);
471 }
472 // decode number into exponent and significand
473 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
474 sig_x.w[0] = x.w[0];
475 // check for zero or non-canonical
476 if ((sig_x.w[1] > 0x0001ed09bead87c0ull)
477 || ((sig_x.w[1] == 0x0001ed09bead87c0ull)
b2a00c89 478 && (sig_x.w[0] > 0x378d8e63ffffffffull))
200359e8
L
479 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)
480 || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
481 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
482 res = negativeZero;
483 } else {
484 res = positiveZero;
485 }
486 BID_RETURN (res);
487 }
488 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
489 // if exponent is less than -6176, the number may be subnormal
490 // (less than the smallest normal value)
491 // the smallest normal value is 1 x 10^-6143 = 10^33 x 10^-6176
492 // if (exp_x - 6176 < -6143)
b2a00c89 493 if (exp_x < 33) { // sig_x * 10^exp_x
200359e8
L
494 if (exp_x > 19) {
495 __mul_128x128_to_256 (sig_x_prime256, sig_x,
b2a00c89 496 ten2k128[exp_x - 20]);
200359e8
L
497 // 10^33 = 0x0000314dc6448d93_38c15b0a00000000
498 if ((sig_x_prime256.w[3] == 0) && (sig_x_prime256.w[2] == 0)
b2a00c89
L
499 && ((sig_x_prime256.w[1] < 0x0000314dc6448d93ull)
500 || ((sig_x_prime256.w[1] == 0x0000314dc6448d93ull)
501 && (sig_x_prime256.w[0] < 0x38c15b0a00000000ull)))) {
502 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? negativeSubnormal :
503 positiveSubnormal;
504 BID_RETURN (res);
200359e8
L
505 }
506 } else {
b2a00c89 507 __mul_64x128_to_192 (sig_x_prime192, ten2k64[exp_x], sig_x);
200359e8
L
508 // 10^33 = 0x0000314dc6448d93_38c15b0a00000000
509 if ((sig_x_prime192.w[2] == 0)
b2a00c89
L
510 && ((sig_x_prime192.w[1] < 0x0000314dc6448d93ull)
511 || ((sig_x_prime192.w[1] == 0x0000314dc6448d93ull)
512 && (sig_x_prime192.w[0] < 0x38c15b0a00000000ull)))) {
513 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? negativeSubnormal :
514 positiveSubnormal;
515 BID_RETURN (res);
200359e8
L
516 }
517 }
518 }
519 // otherwise, normal number, determine the sign
520 res =
521 ((x.w[1] & MASK_SIGN) ==
522 MASK_SIGN) ? negativeNormal : positiveNormal;
523 BID_RETURN (res);
524}
525
526// true if the exponents of x and y are the same, false otherwise.
527// The special cases of sameQuantum(NaN, NaN) and sameQuantum(Inf, Inf) are true
528// If exactly one operand is infinite or exactly one operand is NaN, then false
529#if DECIMAL_CALL_BY_REFERENCE
530void
b2a00c89
L
531bid128_sameQuantum (int *pres, UINT128 * px,
532 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
533 UINT128 x = *px;
534 UINT128 y = *py;
535#else
536int
b2a00c89
L
537bid128_sameQuantum (UINT128 x,
538 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
539#endif
540 int res;
b2a00c89 541 UINT64 x_exp, y_exp;
200359e8 542
b2a00c89
L
543 BID_SWAP128 (x);
544 BID_SWAP128 (y);
200359e8
L
545 // if both operands are NaN, return true
546 if ((x.w[1] & MASK_NAN) == MASK_NAN
547 || ((y.w[1] & MASK_NAN) == MASK_NAN)) {
548 res = ((x.w[1] & MASK_NAN) == MASK_NAN
b2a00c89 549 && (y.w[1] & MASK_NAN) == MASK_NAN);
200359e8
L
550 BID_RETURN (res);
551 }
552 // if both operands are INF, return true
553 if ((x.w[1] & MASK_INF) == MASK_INF
554 || (y.w[1] & MASK_INF) == MASK_INF) {
555 res = ((x.w[1] & MASK_INF) == MASK_INF)
556 && ((y.w[1] & MASK_INF) == MASK_INF);
557 BID_RETURN (res);
558 }
559 // decode exponents for both numbers, and return true if they match
b2a00c89
L
560 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
561 x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
562 } else { // G0_G1 != 11
563 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
564 }
565 if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
566 y_exp = (y.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
567 } else { // G0_G1 != 11
568 y_exp = y.w[1] & MASK_EXP; // biased and shifted left 49 bits
569 }
570 res = (x_exp == y_exp);
200359e8
L
571 BID_RETURN (res);
572}
573
574#if DECIMAL_CALL_BY_REFERENCE
575void
b2a00c89
L
576bid128_totalOrder (int *pres, UINT128 * px,
577 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
578 UINT128 x = *px;
579 UINT128 y = *py;
580#else
581int
b2a00c89
L
582bid128_totalOrder (UINT128 x,
583 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
584#endif
585 int res;
586 int exp_x, exp_y;
587 UINT128 sig_x, sig_y, pyld_y, pyld_x;
588 UINT192 sig_n_prime192;
589 UINT256 sig_n_prime256;
590 char x_is_zero = 0, y_is_zero = 0;
591
b2a00c89
L
592 BID_SWAP128 (x);
593 BID_SWAP128 (y);
200359e8
L
594 // NaN (CASE 1)
595 // if x and y are unordered numerically because either operand is NaN
596 // (1) totalOrder(-NaN, number) is true
597 // (2) totalOrder(number, +NaN) is true
598 // (3) if x and y are both NaN:
599 // i) negative sign bit < positive sign bit
b2a00c89 600 // ii) signaling < quiet for +NaN, reverse for -NaN
200359e8 601 // iii) lesser payload < greater payload for +NaN (reverse for -NaN)
b2a00c89 602 // iv) else if bitwise identical (in canonical form), return 1
200359e8
L
603 if ((x.w[1] & MASK_NAN) == MASK_NAN) {
604 // if x is -NaN
605 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
606 // return true, unless y is -NaN also
607 if ((y.w[1] & MASK_NAN) != MASK_NAN
b2a00c89
L
608 || (y.w[1] & MASK_SIGN) != MASK_SIGN) {
609 res = 1; // y is a number, return 1
610 BID_RETURN (res);
611 } else { // if y and x are both -NaN
612 pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull;
613 pyld_x.w[0] = x.w[0];
614 pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull;
615 pyld_y.w[0] = y.w[0];
616 if ((pyld_x.w[1] > 0x0000314dc6448d93ull)
617 || ((pyld_x.w[1] == 0x0000314dc6448d93ull)
618 && (pyld_x.w[0] > 0x38c15b09ffffffffull))) {
619 pyld_x.w[1] = 0;
620 pyld_x.w[0] = 0;
621 }
622 if ((pyld_y.w[1] > 0x0000314dc6448d93ull)
623 || ((pyld_y.w[1] == 0x0000314dc6448d93ull)
624 && (pyld_y.w[0] > 0x38c15b09ffffffffull))) {
625 pyld_y.w[1] = 0;
626 pyld_y.w[0] = 0;
627 }
628 // if x and y are both -SNaN or both -QNaN, we have to compare payloads
629 // this statement evaluates to true if both are SNaN or QNaN
630 if (!
631 (((y.w[1] & MASK_SNAN) == MASK_SNAN) ^
632 ((x.w[1] & MASK_SNAN) == MASK_SNAN))) {
633 // it comes down to the payload. we want to return true if x has a
634 // larger payload, or if the payloads are equal (canonical forms
635 // are bitwise identical)
636 if ((pyld_x.w[1] > pyld_y.w[1]) ||
637 ((pyld_x.w[1] == pyld_y.w[1])
638 && (pyld_x.w[0] >= pyld_y.w[0])))
639 res = 1;
640 else
641 res = 0;
642 BID_RETURN (res);
643 } else {
644 // either x = -SNaN and y = -QNaN or x = -QNaN and y = -SNaN
645 res = ((y.w[1] & MASK_SNAN) == MASK_SNAN);
646 // totalOrder (-QNaN, -SNaN) == 1
647 BID_RETURN (res);
648 }
200359e8 649 }
b2a00c89 650 } else { // x is +NaN
200359e8
L
651 // return false, unless y is +NaN also
652 if ((y.w[1] & MASK_NAN) != MASK_NAN
b2a00c89
L
653 || (y.w[1] & MASK_SIGN) == MASK_SIGN) {
654 res = 0; // y is a number, return 1
655 BID_RETURN (res);
200359e8 656 } else {
b2a00c89
L
657 // x and y are both +NaN;
658 pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull;
659 pyld_x.w[0] = x.w[0];
660 pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull;
661 pyld_y.w[0] = y.w[0];
662 if ((pyld_x.w[1] > 0x0000314dc6448d93ull)
663 || ((pyld_x.w[1] == 0x0000314dc6448d93ull)
664 && (pyld_x.w[0] > 0x38c15b09ffffffffull))) {
665 pyld_x.w[1] = 0;
666 pyld_x.w[0] = 0;
667 }
668 if ((pyld_y.w[1] > 0x0000314dc6448d93ull)
669 || ((pyld_y.w[1] == 0x0000314dc6448d93ull)
670 && (pyld_y.w[0] > 0x38c15b09ffffffffull))) {
671 pyld_y.w[1] = 0;
672 pyld_y.w[0] = 0;
673 }
674 // if x and y are both +SNaN or both +QNaN, we have to compare payloads
675 // this statement evaluates to true if both are SNaN or QNaN
676 if (!
677 (((y.w[1] & MASK_SNAN) == MASK_SNAN) ^
678 ((x.w[1] & MASK_SNAN) == MASK_SNAN))) {
679 // it comes down to the payload. we want to return true if x has a
680 // smaller payload, or if the payloads are equal (canonical forms
681 // are bitwise identical)
682 if ((pyld_x.w[1] < pyld_y.w[1]) ||
683 ((pyld_x.w[1] == pyld_y.w[1])
684 && (pyld_x.w[0] <= pyld_y.w[0])))
685 res = 1;
686 else
687 res = 0;
688 BID_RETURN (res);
689 } else {
690 // either x = SNaN and y = QNaN or x = QNaN and y = SNaN
691 res = ((x.w[1] & MASK_SNAN) == MASK_SNAN);
692 // totalOrder (-QNaN, -SNaN) == 1
693 BID_RETURN (res);
694 }
200359e8
L
695 }
696 }
697 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {
698 // x is certainly not NAN in this case.
699 // return true if y is positive
700 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
701 BID_RETURN (res);
702 }
703 // SIMPLE (CASE 2)
704 // if all the bits are the same, the numbers are equal.
705 if ((x.w[1] == y.w[1]) && (x.w[0] == y.w[0])) {
706 res = 1;
707 BID_RETURN (res);
708 }
709 // OPPOSITE SIGNS (CASE 3)
710 // if signs are opposite, return 1 if x is negative
711 // (if x < y, totalOrder is true)
b2a00c89
L
712 if (((x.w[1] & MASK_SIGN) == MASK_SIGN) ^ ((y.w[1] & MASK_SIGN) ==
713 MASK_SIGN)) {
200359e8
L
714 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
715 BID_RETURN (res);
716 }
717 // INFINITY (CASE 4)
718 if ((x.w[1] & MASK_INF) == MASK_INF) {
719 // if x == neg_inf, return (y == neg_inf);
720 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) {
721 res = 1;
722 BID_RETURN (res);
723 } else {
724 // x is positive infinity, only return1 if y is positive infinity as well
725 res = ((y.w[1] & MASK_INF) == MASK_INF);
726 BID_RETURN (res);
727 // && (y & MASK_SIGN) != MASK_SIGN); (we know y has same sign as x)
728 }
729 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
730 // x is finite, so:
731 // if y is +inf, x<y
732 // if y is -inf, x>y
733 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
734 BID_RETURN (res);
735 }
736 // CONVERT x
737 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
738 sig_x.w[0] = x.w[0];
739 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
740
741 // CHECK IF x IS CANONICAL
742 // 9999999999999999999999999999999999 (decimal) =
743 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
744 // [0, 10^34) is the 754r supported canonical range.
745 // If the value exceeds that, it is interpreted as 0.
b2a00c89
L
746 if ((((sig_x.w[1] > 0x0001ed09bead87c0ull) ||
747 ((sig_x.w[1] == 0x0001ed09bead87c0ull) &&
748 (sig_x.w[0] > 0x378d8e63ffffffffull))) &&
749 ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
750 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
200359e8
L
751 ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
752 x_is_zero = 1;
753 // check for the case where the exponent is shifted right by 2 bits!
754 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
755 exp_x = (x.w[1] >> 47) & 0x000000000003fffull;
756 }
757 }
758 // CONVERT y
759 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
760 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
761 sig_y.w[0] = y.w[0];
762
763 // CHECK IF y IS CANONICAL
764 // 9999999999999999999999999999999999(decimal) =
765 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
766 // [0, 10^34) is the 754r supported canonical range.
767 // If the value exceeds that, it is interpreted as 0.
b2a00c89
L
768 if ((((sig_y.w[1] > 0x0001ed09bead87c0ull) ||
769 ((sig_y.w[1] == 0x0001ed09bead87c0ull) &&
770 (sig_y.w[0] > 0x378d8e63ffffffffull))) &&
771 ((y.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
772 ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
200359e8
L
773 ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
774 y_is_zero = 1;
775 // check for the case where the exponent is shifted right by 2 bits!
776 if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
777 exp_y = (y.w[1] >> 47) & 0x000000000003fffull;
778 }
779 }
780 // ZERO (CASE 5)
781 // if x and y represent the same entities, and both are negative
782 // return true iff exp_x <= exp_y
783 if (x_is_zero && y_is_zero) {
784 // we know that signs must be the same because we would have caught it
785 // in case3 if signs were different
786 // totalOrder(x,y) iff exp_x >= exp_y for negative numbers
787 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
788 if (exp_x == exp_y) {
789 res = 1;
790 BID_RETURN (res);
791 }
792 res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
793 BID_RETURN (res);
794 }
795 // if x is zero and y isn't, clearly x has the smaller payload
796 if (x_is_zero) {
797 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN);
798 BID_RETURN (res);
799 }
800 // if y is zero, and x isn't, clearly y has the smaller payload
801 if (y_is_zero) {
802 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
803 BID_RETURN (res);
804 }
805 // REDUNDANT REPRESENTATIONS (CASE 6)
806 // if both components are either bigger or smaller
807 if (((sig_x.w[1] > sig_y.w[1])
808 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
809 && exp_x >= exp_y) {
810 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
811 BID_RETURN (res);
812 }
813 if (((sig_x.w[1] < sig_y.w[1])
814 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
815 && exp_x <= exp_y) {
816 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
817 BID_RETURN (res);
818 }
819 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
820 if (exp_x > exp_y) {
821 // if exp_x is 33 greater than exp_y, it is definitely larger,
822 // so no need for compensation
823 if (exp_x - exp_y > 33) {
824 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN);
825 BID_RETURN (res);
826 // difference cannot be greater than 10^33
827 }
828 // otherwise adjust the x significand upwards
829 if (exp_x - exp_y > 19) {
830 __mul_128x128_to_256 (sig_n_prime256, sig_x,
b2a00c89 831 ten2k128[exp_x - exp_y - 20]);
200359e8
L
832 // the compensated significands are equal (ie "x and y represent the same
833 // entities") return 1 if (negative && expx > expy) ||
834 // (positive && expx < expy)
835 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
b2a00c89
L
836 && (sig_n_prime256.w[1] == sig_y.w[1])
837 && (sig_n_prime256.w[0] == sig_y.w[0])) {
838 // the case exp_x == exp_y cannot occur, because all bits must be
839 // the same - would have been caught if (x == y)
840 res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
841 BID_RETURN (res);
200359e8
L
842 }
843 // if positive, return 1 if adjusted x is smaller than y
844 res = (((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
b2a00c89
L
845 && ((sig_n_prime256.w[1] < sig_y.w[1])
846 || (sig_n_prime256.w[1] == sig_y.w[1]
847 && sig_n_prime256.w[0] <
848 sig_y.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
849 MASK_SIGN));
200359e8
L
850 BID_RETURN (res);
851 }
b2a00c89 852 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_x - exp_y], sig_x);
200359e8
L
853 // if positive, return whichever significand is larger
854 // (converse if negative)
855 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
b2a00c89 856 && (sig_n_prime192.w[0] == sig_y.w[0])) {
200359e8
L
857 res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
858 BID_RETURN (res);
859 }
860 res = (((sig_n_prime192.w[2] == 0)
b2a00c89
L
861 && ((sig_n_prime192.w[1] < sig_y.w[1])
862 || (sig_n_prime192.w[1] == sig_y.w[1]
863 && sig_n_prime192.w[0] <
864 sig_y.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
865 MASK_SIGN));
200359e8
L
866 BID_RETURN (res);
867 }
868 // if exp_x is 33 less than exp_y, it is definitely smaller,
869 // no need for compensation
870 if (exp_y - exp_x > 33) {
871 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN);
872 BID_RETURN (res);
873 }
874 if (exp_y - exp_x > 19) {
875 // adjust the y significand upwards
876 __mul_128x128_to_256 (sig_n_prime256, sig_y,
b2a00c89 877 ten2k128[exp_y - exp_x - 20]);
200359e8
L
878 // if x and y represent the same entities and both are negative
879 // return true iff exp_x <= exp_y
880 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
b2a00c89
L
881 && (sig_n_prime256.w[1] == sig_x.w[1])
882 && (sig_n_prime256.w[0] == sig_x.w[0])) {
200359e8
L
883 res = (exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN);
884 BID_RETURN (res);
885 }
886 // values are not equal, for positive numbers return 1 if x is less than y
887 // and 0 otherwise
888 res = (((sig_n_prime256.w[3] != 0) ||
b2a00c89
L
889 // if upper128 bits of compensated y are non-zero, y is bigger
890 (sig_n_prime256.w[2] != 0) ||
891 // if upper128 bits of compensated y are non-zero, y is bigger
892 (sig_n_prime256.w[1] > sig_x.w[1]) ||
893 // if compensated y is bigger, y is bigger
894 (sig_n_prime256.w[1] == sig_x.w[1]
895 && sig_n_prime256.w[0] >
896 sig_x.w[0])) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
200359e8
L
897 BID_RETURN (res);
898 }
b2a00c89 899 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y);
200359e8
L
900 if ((sig_n_prime192.w[2] == 0) && (sig_n_prime192.w[1] == sig_x.w[1])
901 && (sig_n_prime192.w[0] == sig_x.w[0])) {
902 res = (exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN);
903 BID_RETURN (res);
904 }
905 res = (((sig_n_prime192.w[2] != 0) ||
b2a00c89
L
906 // if upper128 bits of compensated y are non-zero, y is bigger
907 (sig_n_prime192.w[1] > sig_x.w[1]) ||
908 // if compensated y is bigger, y is bigger
909 (sig_n_prime192.w[1] == sig_x.w[1]
910 && sig_n_prime192.w[0] >
911 sig_x.w[0])) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN));
200359e8
L
912 BID_RETURN (res);
913}
914
915#if DECIMAL_CALL_BY_REFERENCE
916void
b2a00c89
L
917bid128_totalOrderMag (int *pres, UINT128 * px,
918 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
919 UINT128 x = *px;
920 UINT128 y = *py;
921#else
922int
b2a00c89
L
923bid128_totalOrderMag (UINT128 x,
924 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
925#endif
926 int res;
927 int exp_x, exp_y;
928 UINT128 sig_x, sig_y, pyld_y, pyld_x;
929 UINT192 sig_n_prime192;
930 UINT256 sig_n_prime256;
931 char x_is_zero = 0, y_is_zero = 0;
932
b2a00c89
L
933 BID_SWAP128 (x);
934 BID_SWAP128 (y);
200359e8
L
935 x.w[1] = x.w[1] & 0x7fffffffffffffffull;
936 y.w[1] = y.w[1] & 0x7fffffffffffffffull;
937
938 // NaN (CASE 1)
939 // if x and y are unordered numerically because either operand is NaN
940 // (1) totalOrder(number, +NaN) is true
941 // (2) if x and y are both NaN:
b2a00c89 942 // i) signaling < quiet for +NaN
200359e8 943 // ii) lesser payload < greater payload for +NaN
b2a00c89 944 // iii) else if bitwise identical (in canonical form), return 1
200359e8
L
945 if ((x.w[1] & MASK_NAN) == MASK_NAN) {
946 // x is +NaN
947 // return false, unless y is +NaN also
948 if ((y.w[1] & MASK_NAN) != MASK_NAN) {
b2a00c89 949 res = 0; // y is a number, return 0
200359e8
L
950 BID_RETURN (res);
951 } else {
952 // x and y are both +NaN;
b2a00c89
L
953 pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull;
954 pyld_x.w[0] = x.w[0];
955 pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull;
956 pyld_y.w[0] = y.w[0];
957 if ((pyld_x.w[1] > 0x0000314dc6448d93ull)
958 || ((pyld_x.w[1] == 0x0000314dc6448d93ull)
959 && (pyld_x.w[0] > 0x38c15b09ffffffffull))) {
960 pyld_x.w[1] = 0;
961 pyld_x.w[0] = 0;
962 }
963 if ((pyld_y.w[1] > 0x0000314dc6448d93ull)
964 || ((pyld_y.w[1] == 0x0000314dc6448d93ull)
965 && (pyld_y.w[0] > 0x38c15b09ffffffffull))) {
966 pyld_y.w[1] = 0;
967 pyld_y.w[0] = 0;
968 }
969 // if x and y are both +SNaN or both +QNaN, we have to compare payloads
970 // this statement evaluates to true if both are SNaN or QNaN
200359e8 971 if (!
b2a00c89
L
972 (((y.w[1] & MASK_SNAN) == MASK_SNAN) ^
973 ((x.w[1] & MASK_SNAN) == MASK_SNAN))) {
974 // it comes down to the payload. we want to return true if x has a
975 // smaller payload, or if the payloads are equal (canonical forms
976 // are bitwise identical)
977 if ((pyld_x.w[1] < pyld_y.w[1]) ||
978 ((pyld_x.w[1] == pyld_y.w[1])
979 && (pyld_x.w[0] <= pyld_y.w[0]))) {
980 res = 1;
981 } else {
982 res = 0;
983 }
984 BID_RETURN (res);
200359e8 985 } else {
b2a00c89
L
986 // either x = SNaN and y = QNaN or x = QNaN and y = SNaN
987 res = ((x.w[1] & MASK_SNAN) == MASK_SNAN);
988 // totalOrder (-QNaN, -SNaN) == 1
989 BID_RETURN (res);
200359e8
L
990 }
991 }
992 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {
993 // x is certainly not NAN in this case.
994 // return true because y is positive
995 res = 1;
996 BID_RETURN (res);
997 }
998 // SIMPLE (CASE 2)
999 // if all the bits are the same, the numbers are equal.
1000 if ((x.w[1] == y.w[1]) && (x.w[0] == y.w[0])) {
1001 res = 1;
1002 BID_RETURN (res);
1003 }
1004 // INFINITY (CASE 3)
1005 if ((x.w[1] & MASK_INF) == MASK_INF) {
1006 // x is positive infinity, only return 1 if y is positive infinity as well
1007 res = ((y.w[1] & MASK_INF) == MASK_INF);
1008 BID_RETURN (res);
1009 // (we know y has same sign as x)
1010 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
1011 // x is finite, so:
1012 // since y is +inf, x<y
1013 res = 1;
1014 BID_RETURN (res);
1015 } else {
b2a00c89 1016 ; // continue
200359e8
L
1017 }
1018
1019 // CONVERT x
1020 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
1021 sig_x.w[0] = x.w[0];
1022 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
1023
1024 // CHECK IF x IS CANONICAL
1025 // 9999999999999999999999999999999999 (decimal) =
1026 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1027 // [0, 10^34) is the 754r supported canonical range.
1028 // If the value exceeds that, it is interpreted as 0.
b2a00c89
L
1029 if ((((sig_x.w[1] > 0x0001ed09bead87c0ull) ||
1030 ((sig_x.w[1] == 0x0001ed09bead87c0ull) &&
1031 (sig_x.w[0] > 0x378d8e63ffffffffull))) &&
1032 ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
1033 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
200359e8
L
1034 ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) {
1035 x_is_zero = 1;
1036 // check for the case where the exponent is shifted right by 2 bits!
1037 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
1038 exp_x = (x.w[1] >> 47) & 0x000000000003fffull;
1039 }
1040 }
1041 // CONVERT y
1042 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
1043 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
1044 sig_y.w[0] = y.w[0];
1045
1046 // CHECK IF y IS CANONICAL
1047 // 9999999999999999999999999999999999(decimal) =
1048 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal)
1049 // [0, 10^34) is the 754r supported canonical range.
1050 // If the value exceeds that, it is interpreted as 0.
b2a00c89
L
1051 if ((((sig_y.w[1] > 0x0001ed09bead87c0ull) ||
1052 ((sig_y.w[1] == 0x0001ed09bead87c0ull) &&
1053 (sig_y.w[0] > 0x378d8e63ffffffffull))) &&
1054 ((y.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
1055 ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
200359e8
L
1056 ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) {
1057 y_is_zero = 1;
1058 // check for the case where the exponent is shifted right by 2 bits!
1059 if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
1060 exp_y = (y.w[1] >> 47) & 0x000000000003fffull;
1061 }
1062 }
1063 // ZERO (CASE 4)
1064 if (x_is_zero && y_is_zero) {
1065 // we know that signs must be the same because we would have caught it
1066 // in case3 if signs were different
1067 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
1068 if (exp_x == exp_y) {
1069 res = 1;
1070 BID_RETURN (res);
1071 }
1072 res = (exp_x <= exp_y);
1073 BID_RETURN (res);
1074 }
1075 // if x is zero and y isn't, clearly x has the smaller payload
1076 if (x_is_zero) {
1077 res = 1;
1078 BID_RETURN (res);
1079 }
1080 // if y is zero, and x isn't, clearly y has the smaller payload
1081 if (y_is_zero) {
1082 res = 0;
1083 BID_RETURN (res);
1084 }
1085 // REDUNDANT REPRESENTATIONS (CASE 5)
1086 // if both components are either bigger or smaller
1087 if (((sig_x.w[1] > sig_y.w[1])
1088 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
1089 && exp_x >= exp_y) {
1090 res = 0;
1091 BID_RETURN (res);
1092 }
1093 if (((sig_x.w[1] < sig_y.w[1])
1094 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
1095 && exp_x <= exp_y) {
1096 res = 1;
1097 BID_RETURN (res);
1098 }
1099 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
1100 if (exp_x > exp_y) {
1101 // if exp_x is 33 greater than exp_y, it is definitely larger,
1102 // so no need for compensation
1103 if (exp_x - exp_y > 33) {
b2a00c89 1104 res = 0; // difference cannot be greater than 10^33
200359e8
L
1105 BID_RETURN (res);
1106 }
1107 // otherwise adjust the x significand upwards
1108 if (exp_x - exp_y > 19) {
1109 __mul_128x128_to_256 (sig_n_prime256, sig_x,
b2a00c89 1110 ten2k128[exp_x - exp_y - 20]);
200359e8
L
1111 // the compensated significands are equal (ie "x and y represent the same
1112 // entities") return 1 if (negative && expx > expy) ||
1113 // (positive && expx < expy)
1114 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
b2a00c89
L
1115 && (sig_n_prime256.w[1] == sig_y.w[1])
1116 && (sig_n_prime256.w[0] == sig_y.w[0])) {
1117 // the case (exp_x == exp_y) cannot occur, because all bits must be
1118 // the same - would have been caught if (x == y)
1119 res = (exp_x <= exp_y);
1120 BID_RETURN (res);
200359e8
L
1121 }
1122 // since positive, return 1 if adjusted x is smaller than y
1123 res = ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
b2a00c89
L
1124 && ((sig_n_prime256.w[1] < sig_y.w[1])
1125 || (sig_n_prime256.w[1] == sig_y.w[1]
1126 && sig_n_prime256.w[0] < sig_y.w[0])));
200359e8
L
1127 BID_RETURN (res);
1128 }
b2a00c89 1129 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_x - exp_y], sig_x);
200359e8
L
1130 // if positive, return whichever significand is larger
1131 // (converse if negative)
1132 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
b2a00c89 1133 && (sig_n_prime192.w[0] == sig_y.w[0])) {
200359e8
L
1134 res = (exp_x <= exp_y);
1135 BID_RETURN (res);
1136 }
1137 res = ((sig_n_prime192.w[2] == 0)
b2a00c89
L
1138 && ((sig_n_prime192.w[1] < sig_y.w[1])
1139 || (sig_n_prime192.w[1] == sig_y.w[1]
1140 && sig_n_prime192.w[0] < sig_y.w[0])));
200359e8
L
1141 BID_RETURN (res);
1142 }
1143 // if exp_x is 33 less than exp_y, it is definitely smaller,
1144 // no need for compensation
1145 if (exp_y - exp_x > 33) {
1146 res = 1;
1147 BID_RETURN (res);
1148 }
1149 if (exp_y - exp_x > 19) {
1150 // adjust the y significand upwards
1151 __mul_128x128_to_256 (sig_n_prime256, sig_y,
b2a00c89 1152 ten2k128[exp_y - exp_x - 20]);
200359e8 1153 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0)
b2a00c89
L
1154 && (sig_n_prime256.w[1] == sig_x.w[1])
1155 && (sig_n_prime256.w[0] == sig_x.w[0])) {
200359e8
L
1156 res = (exp_x <= exp_y);
1157 BID_RETURN (res);
1158 }
1159 // values are not equal, for positive numbers return 1 if x is less than y
1160 // and 0 otherwise
1161 res = ((sig_n_prime256.w[3] != 0) ||
b2a00c89
L
1162 // if upper128 bits of compensated y are non-zero, y is bigger
1163 (sig_n_prime256.w[2] != 0) ||
1164 // if upper128 bits of compensated y are non-zero, y is bigger
1165 (sig_n_prime256.w[1] > sig_x.w[1]) ||
1166 // if compensated y is bigger, y is bigger
1167 (sig_n_prime256.w[1] == sig_x.w[1]
1168 && sig_n_prime256.w[0] > sig_x.w[0]));
200359e8
L
1169 BID_RETURN (res);
1170 }
b2a00c89 1171 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y);
200359e8
L
1172 if ((sig_n_prime192.w[2] == 0) && (sig_n_prime192.w[1] == sig_x.w[1])
1173 && (sig_n_prime192.w[0] == sig_x.w[0])) {
1174 res = (exp_x <= exp_y);
1175 BID_RETURN (res);
1176 }
1177 res = ((sig_n_prime192.w[2] != 0) ||
b2a00c89
L
1178 // if upper128 bits of compensated y are non-zero, y is bigger
1179 (sig_n_prime192.w[1] > sig_x.w[1]) ||
1180 // if compensated y is bigger, y is bigger
1181 (sig_n_prime192.w[1] == sig_x.w[1]
1182 && sig_n_prime192.w[0] > sig_x.w[0]));
200359e8
L
1183 BID_RETURN (res);
1184}
1185
1186#if DECIMAL_CALL_BY_REFERENCE
1187void
b2a00c89 1188bid128_radix (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
1189 UINT128 x = *px;
1190#else
1191int
b2a00c89 1192bid128_radix (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200359e8
L
1193#endif
1194 int res;
b2a00c89 1195 if (x.w[LOW_128W]) // dummy test
200359e8
L
1196 res = 10;
1197 else
1198 res = 10;
1199 BID_RETURN (res);
1200}