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