Daily bump.
[official-gcc.git] / libgcc / config / libbid / bid64_noncomp.c
blobea804c444d407c0ad56f1d027d19324b818cb55a
1 /* Copyright (C) 2007-2017 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
24 #include "bid_internal.h"
26 static const UINT64 mult_factor[16] = {
27 1ull, 10ull, 100ull, 1000ull,
28 10000ull, 100000ull, 1000000ull, 10000000ull,
29 100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
30 1000000000000ull, 10000000000000ull,
31 100000000000000ull, 1000000000000000ull
34 /*****************************************************************************
35 * BID64 non-computational functions:
36 * - bid64_isSigned
37 * - bid64_isNormal
38 * - bid64_isSubnormal
39 * - bid64_isFinite
40 * - bid64_isZero
41 * - bid64_isInf
42 * - bid64_isSignaling
43 * - bid64_isCanonical
44 * - bid64_isNaN
45 * - bid64_copy
46 * - bid64_negate
47 * - bid64_abs
48 * - bid64_copySign
49 * - bid64_class
50 * - bid64_sameQuantum
51 * - bid64_totalOrder
52 * - bid64_totalOrderMag
53 * - bid64_radix
54 ****************************************************************************/
56 #if DECIMAL_CALL_BY_REFERENCE
57 void
58 bid64_isSigned (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
59 UINT64 x = *px;
60 #else
61 int
62 bid64_isSigned (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
63 #endif
64 int res;
66 res = ((x & MASK_SIGN) == MASK_SIGN);
67 BID_RETURN (res);
70 // return 1 iff x is not zero, nor NaN nor subnormal nor infinity
71 #if DECIMAL_CALL_BY_REFERENCE
72 void
73 bid64_isNormal (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
74 UINT64 x = *px;
75 #else
76 int
77 bid64_isNormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
78 #endif
79 int res;
80 UINT128 sig_x_prime;
81 UINT64 sig_x;
82 unsigned int exp_x;
84 if ((x & MASK_INF) == MASK_INF) { // x is either INF or NaN
85 res = 0;
86 } else {
87 // decode number into exponent and significand
88 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
89 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
90 // check for zero or non-canonical
91 if (sig_x > 9999999999999999ull || sig_x == 0) {
92 res = 0; // zero or non-canonical
93 BID_RETURN (res);
95 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
96 } else {
97 sig_x = (x & MASK_BINARY_SIG1);
98 if (sig_x == 0) {
99 res = 0; // zero
100 BID_RETURN (res);
102 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
104 // if exponent is less than -383, the number may be subnormal
105 // if (exp_x - 398 = -383) the number may be subnormal
106 if (exp_x < 15) {
107 __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
108 if (sig_x_prime.w[1] == 0
109 && sig_x_prime.w[0] < 1000000000000000ull) {
110 res = 0; // subnormal
111 } else {
112 res = 1; // normal
114 } else {
115 res = 1; // normal
118 BID_RETURN (res);
121 // return 1 iff x is not zero, nor NaN nor normal nor infinity
122 #if DECIMAL_CALL_BY_REFERENCE
123 void
124 bid64_isSubnormal (int *pres,
125 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
126 UINT64 x = *px;
127 #else
129 bid64_isSubnormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
130 #endif
131 int res;
132 UINT128 sig_x_prime;
133 UINT64 sig_x;
134 unsigned int exp_x;
136 if ((x & MASK_INF) == MASK_INF) { // x is either INF or NaN
137 res = 0;
138 } else {
139 // decode number into exponent and significand
140 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
141 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
142 // check for zero or non-canonical
143 if (sig_x > 9999999999999999ull || sig_x == 0) {
144 res = 0; // zero or non-canonical
145 BID_RETURN (res);
147 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
148 } else {
149 sig_x = (x & MASK_BINARY_SIG1);
150 if (sig_x == 0) {
151 res = 0; // zero
152 BID_RETURN (res);
154 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
156 // if exponent is less than -383, the number may be subnormal
157 // if (exp_x - 398 = -383) the number may be subnormal
158 if (exp_x < 15) {
159 __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
160 if (sig_x_prime.w[1] == 0
161 && sig_x_prime.w[0] < 1000000000000000ull) {
162 res = 1; // subnormal
163 } else {
164 res = 0; // normal
166 } else {
167 res = 0; // normal
170 BID_RETURN (res);
173 //iff x is zero, subnormal or normal (not infinity or NaN)
174 #if DECIMAL_CALL_BY_REFERENCE
175 void
176 bid64_isFinite (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
177 UINT64 x = *px;
178 #else
180 bid64_isFinite (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
181 #endif
182 int res;
184 res = ((x & MASK_INF) != MASK_INF);
185 BID_RETURN (res);
188 #if DECIMAL_CALL_BY_REFERENCE
189 void
190 bid64_isZero (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
191 UINT64 x = *px;
192 #else
194 bid64_isZero (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
195 #endif
196 int res;
198 // if infinity or nan, return 0
199 if ((x & MASK_INF) == MASK_INF) {
200 res = 0;
201 } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
202 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1]
203 // => sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
204 // if(sig_x > 9999999999999999ull) {return 1;}
205 res =
206 (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
207 9999999999999999ull);
208 } else {
209 res = ((x & MASK_BINARY_SIG1) == 0);
211 BID_RETURN (res);
214 #if DECIMAL_CALL_BY_REFERENCE
215 void
216 bid64_isInf (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
217 UINT64 x = *px;
218 #else
220 bid64_isInf (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
221 #endif
222 int res;
224 res = ((x & MASK_INF) == MASK_INF) && ((x & MASK_NAN) != MASK_NAN);
225 BID_RETURN (res);
228 #if DECIMAL_CALL_BY_REFERENCE
229 void
230 bid64_isSignaling (int *pres,
231 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
232 UINT64 x = *px;
233 #else
235 bid64_isSignaling (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
236 #endif
237 int res;
239 res = ((x & MASK_SNAN) == MASK_SNAN);
240 BID_RETURN (res);
243 #if DECIMAL_CALL_BY_REFERENCE
244 void
245 bid64_isCanonical (int *pres,
246 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
247 UINT64 x = *px;
248 #else
250 bid64_isCanonical (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
251 #endif
252 int res;
254 if ((x & MASK_NAN) == MASK_NAN) { // NaN
255 if (x & 0x01fc000000000000ull) {
256 res = 0;
257 } else if ((x & 0x0003ffffffffffffull) > 999999999999999ull) { // payload
258 res = 0;
259 } else {
260 res = 1;
262 } else if ((x & MASK_INF) == MASK_INF) {
263 if (x & 0x03ffffffffffffffull) {
264 res = 0;
265 } else {
266 res = 1;
268 } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // 54-bit coeff.
269 res =
270 (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) <=
271 9999999999999999ull);
272 } else { // 53-bit coeff.
273 res = 1;
275 BID_RETURN (res);
278 #if DECIMAL_CALL_BY_REFERENCE
279 void
280 bid64_isNaN (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
281 UINT64 x = *px;
282 #else
284 bid64_isNaN (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
285 #endif
286 int res;
288 res = ((x & MASK_NAN) == MASK_NAN);
289 BID_RETURN (res);
292 // copies a floating-point operand x to destination y, with no change
293 #if DECIMAL_CALL_BY_REFERENCE
294 void
295 bid64_copy (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
296 UINT64 x = *px;
297 #else
298 UINT64
299 bid64_copy (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
300 #endif
301 UINT64 res;
303 res = x;
304 BID_RETURN (res);
307 // copies a floating-point operand x to destination y, reversing the sign
308 #if DECIMAL_CALL_BY_REFERENCE
309 void
310 bid64_negate (UINT64 * pres,
311 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
312 UINT64 x = *px;
313 #else
314 UINT64
315 bid64_negate (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
316 #endif
317 UINT64 res;
319 res = x ^ MASK_SIGN;
320 BID_RETURN (res);
323 // copies a floating-point operand x to destination y, changing the sign to positive
324 #if DECIMAL_CALL_BY_REFERENCE
325 void
326 bid64_abs (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
327 UINT64 x = *px;
328 #else
329 UINT64
330 bid64_abs (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
331 #endif
332 UINT64 res;
334 res = x & ~MASK_SIGN;
335 BID_RETURN (res);
338 // copies operand x to destination in the same format as x, but
339 // with the sign of y
340 #if DECIMAL_CALL_BY_REFERENCE
341 void
342 bid64_copySign (UINT64 * pres, UINT64 * px,
343 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
344 UINT64 x = *px;
345 UINT64 y = *py;
346 #else
347 UINT64
348 bid64_copySign (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
349 #endif
350 UINT64 res;
352 res = (x & ~MASK_SIGN) | (y & MASK_SIGN);
353 BID_RETURN (res);
356 #if DECIMAL_CALL_BY_REFERENCE
357 void
358 bid64_class (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
359 UINT64 x = *px;
360 #else
362 bid64_class (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
363 #endif
364 int res;
365 UINT128 sig_x_prime;
366 UINT64 sig_x;
367 int exp_x;
369 if ((x & MASK_NAN) == MASK_NAN) {
370 // is the NaN signaling?
371 if ((x & MASK_SNAN) == MASK_SNAN) {
372 res = signalingNaN;
373 BID_RETURN (res);
375 // if NaN and not signaling, must be quietNaN
376 res = quietNaN;
377 BID_RETURN (res);
378 } else if ((x & MASK_INF) == MASK_INF) {
379 // is the Infinity negative?
380 if ((x & MASK_SIGN) == MASK_SIGN) {
381 res = negativeInfinity;
382 } else {
383 // otherwise, must be positive infinity
384 res = positiveInfinity;
386 BID_RETURN (res);
387 } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
388 // decode number into exponent and significand
389 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
390 // check for zero or non-canonical
391 if (sig_x > 9999999999999999ull || sig_x == 0) {
392 if ((x & MASK_SIGN) == MASK_SIGN) {
393 res = negativeZero;
394 } else {
395 res = positiveZero;
397 BID_RETURN (res);
399 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
400 } else {
401 sig_x = (x & MASK_BINARY_SIG1);
402 if (sig_x == 0) {
403 res =
404 ((x & MASK_SIGN) == MASK_SIGN) ? negativeZero : positiveZero;
405 BID_RETURN (res);
407 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
409 // if exponent is less than -383, number may be subnormal
410 // if (exp_x - 398 < -383)
411 if (exp_x < 15) { // sig_x *10^exp_x
412 __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
413 if (sig_x_prime.w[1] == 0
414 && (sig_x_prime.w[0] < 1000000000000000ull)) {
415 res =
416 ((x & MASK_SIGN) ==
417 MASK_SIGN) ? negativeSubnormal : positiveSubnormal;
418 BID_RETURN (res);
421 // otherwise, normal number, determine the sign
422 res =
423 ((x & MASK_SIGN) == MASK_SIGN) ? negativeNormal : positiveNormal;
424 BID_RETURN (res);
427 // true if the exponents of x and y are the same, false otherwise.
428 // The special cases of sameQuantum (NaN, NaN) and sameQuantum (Inf, Inf) are
429 // true.
430 // If exactly one operand is infinite or exactly one operand is NaN, then false
431 #if DECIMAL_CALL_BY_REFERENCE
432 void
433 bid64_sameQuantum (int *pres, UINT64 * px,
434 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
435 UINT64 x = *px;
436 UINT64 y = *py;
437 #else
439 bid64_sameQuantum (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
440 #endif
441 int res;
442 unsigned int exp_x, exp_y;
444 // if both operands are NaN, return true; if just one is NaN, return false
445 if ((x & MASK_NAN) == MASK_NAN || ((y & MASK_NAN) == MASK_NAN)) {
446 res = ((x & MASK_NAN) == MASK_NAN && (y & MASK_NAN) == MASK_NAN);
447 BID_RETURN (res);
449 // if both operands are INF, return true; if just one is INF, return false
450 if ((x & MASK_INF) == MASK_INF || (y & MASK_INF) == MASK_INF) {
451 res = ((x & MASK_INF) == MASK_INF && (y & MASK_INF) == MASK_INF);
452 BID_RETURN (res);
454 // decode exponents for both numbers, and return true if they match
455 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
456 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
457 } else {
458 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
460 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
461 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
462 } else {
463 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
465 res = (exp_x == exp_y);
466 BID_RETURN (res);
469 #if DECIMAL_CALL_BY_REFERENCE
470 void
471 bid64_totalOrder (int *pres, UINT64 * px,
472 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
473 UINT64 x = *px;
474 UINT64 y = *py;
475 #else
477 bid64_totalOrder (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
478 #endif
479 int res;
480 int exp_x, exp_y;
481 UINT64 sig_x, sig_y, pyld_y, pyld_x;
482 UINT128 sig_n_prime;
483 char x_is_zero = 0, y_is_zero = 0;
485 // NaN (CASE1)
486 // if x and y are unordered numerically because either operand is NaN
487 // (1) totalOrder(-NaN, number) is true
488 // (2) totalOrder(number, +NaN) is true
489 // (3) if x and y are both NaN:
490 // i) negative sign bit < positive sign bit
491 // ii) signaling < quiet for +NaN, reverse for -NaN
492 // iii) lesser payload < greater payload for +NaN (reverse for -NaN)
493 // iv) else if bitwise identical (in canonical form), return 1
494 if ((x & MASK_NAN) == MASK_NAN) {
495 // if x is -NaN
496 if ((x & MASK_SIGN) == MASK_SIGN) {
497 // return true, unless y is -NaN also
498 if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) != MASK_SIGN) {
499 res = 1; // y is a number, return 1
500 BID_RETURN (res);
501 } else { // if y and x are both -NaN
502 // if x and y are both -sNaN or both -qNaN, we have to compare payloads
503 // this xnor statement evaluates to true if both are sNaN or qNaN
504 if (!
505 (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
506 MASK_SNAN))) {
507 // it comes down to the payload. we want to return true if x has a
508 // larger payload, or if the payloads are equal (canonical forms
509 // are bitwise identical)
510 pyld_y = y & 0x0003ffffffffffffull;
511 pyld_x = x & 0x0003ffffffffffffull;
512 if (pyld_y > 999999999999999ull || pyld_y == 0) {
513 // if y is zero, x must be less than or numerically equal
514 // y's payload is 0
515 res = 1;
516 BID_RETURN (res);
518 // if x is zero and y isn't, x has the smaller payload
519 // definitely (since we know y isn't 0 at this point)
520 if (pyld_x > 999999999999999ull || pyld_x == 0) {
521 // x's payload is 0
522 res = 0;
523 BID_RETURN (res);
525 res = (pyld_x >= pyld_y);
526 BID_RETURN (res);
527 } else {
528 // either x = -sNaN and y = -qNaN or x = -qNaN and y = -sNaN
529 res = (y & MASK_SNAN) == MASK_SNAN; // totalOrder(-qNaN, -sNaN) == 1
530 BID_RETURN (res);
533 } else { // x is +NaN
534 // return false, unless y is +NaN also
535 if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) == MASK_SIGN) {
536 res = 0; // y is a number, return 1
537 BID_RETURN (res);
538 } else {
539 // x and y are both +NaN;
540 // must investigate payload if both quiet or both signaling
541 // this xnor statement will be true if both x and y are +qNaN or +sNaN
542 if (!
543 (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
544 MASK_SNAN))) {
545 // it comes down to the payload. we want to return true if x has a
546 // smaller payload, or if the payloads are equal (canonical forms
547 // are bitwise identical)
548 pyld_y = y & 0x0003ffffffffffffull;
549 pyld_x = x & 0x0003ffffffffffffull;
550 // if x is zero and y isn't, x has the smaller
551 // payload definitely (since we know y isn't 0 at this point)
552 if (pyld_x > 999999999999999ull || pyld_x == 0) {
553 res = 1;
554 BID_RETURN (res);
556 if (pyld_y > 999999999999999ull || pyld_y == 0) {
557 // if y is zero, x must be less than or numerically equal
558 res = 0;
559 BID_RETURN (res);
561 res = (pyld_x <= pyld_y);
562 BID_RETURN (res);
563 } else {
564 // return true if y is +qNaN and x is +sNaN
565 // (we know they're different bc of xor if_stmt above)
566 res = ((x & MASK_SNAN) == MASK_SNAN);
567 BID_RETURN (res);
571 } else if ((y & MASK_NAN) == MASK_NAN) {
572 // x is certainly not NAN in this case.
573 // return true if y is positive
574 res = ((y & MASK_SIGN) != MASK_SIGN);
575 BID_RETURN (res);
577 // SIMPLE (CASE2)
578 // if all the bits are the same, these numbers are equal.
579 if (x == y) {
580 res = 1;
581 BID_RETURN (res);
583 // OPPOSITE SIGNS (CASE 3)
584 // if signs are opposite, return 1 if x is negative
585 // (if x<y, totalOrder is true)
586 if (((x & MASK_SIGN) == MASK_SIGN) ^ ((y & MASK_SIGN) == MASK_SIGN)) {
587 res = (x & MASK_SIGN) == MASK_SIGN;
588 BID_RETURN (res);
590 // INFINITY (CASE4)
591 if ((x & MASK_INF) == MASK_INF) {
592 // if x==neg_inf, return (y == neg_inf)?1:0;
593 if ((x & MASK_SIGN) == MASK_SIGN) {
594 res = 1;
595 BID_RETURN (res);
596 } else {
597 // x is positive infinity, only return1 if y
598 // is positive infinity as well
599 // (we know y has same sign as x)
600 res = ((y & MASK_INF) == MASK_INF);
601 BID_RETURN (res);
603 } else if ((y & MASK_INF) == MASK_INF) {
604 // x is finite, so:
605 // if y is +inf, x<y
606 // if y is -inf, x>y
607 res = ((y & MASK_SIGN) != MASK_SIGN);
608 BID_RETURN (res);
610 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
611 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
612 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
613 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
614 if (sig_x > 9999999999999999ull || sig_x == 0) {
615 x_is_zero = 1;
617 } else {
618 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
619 sig_x = (x & MASK_BINARY_SIG1);
620 if (sig_x == 0) {
621 x_is_zero = 1;
625 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
626 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
627 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
628 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
629 if (sig_y > 9999999999999999ull || sig_y == 0) {
630 y_is_zero = 1;
632 } else {
633 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
634 sig_y = (y & MASK_BINARY_SIG1);
635 if (sig_y == 0) {
636 y_is_zero = 1;
640 // ZERO (CASE 5)
641 // if x and y represent the same entities, and
642 // both are negative , return true iff exp_x <= exp_y
643 if (x_is_zero && y_is_zero) {
644 if (!((x & MASK_SIGN) == MASK_SIGN) ^
645 ((y & MASK_SIGN) == MASK_SIGN)) {
646 // if signs are the same:
647 // totalOrder(x,y) iff exp_x >= exp_y for negative numbers
648 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
649 if (exp_x == exp_y) {
650 res = 1;
651 BID_RETURN (res);
653 res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
654 BID_RETURN (res);
655 } else {
656 // signs are different.
657 // totalOrder(-0, +0) is true
658 // totalOrder(+0, -0) is false
659 res = ((x & MASK_SIGN) == MASK_SIGN);
660 BID_RETURN (res);
663 // if x is zero and y isn't, clearly x has the smaller payload.
664 if (x_is_zero) {
665 res = ((y & MASK_SIGN) != MASK_SIGN);
666 BID_RETURN (res);
668 // if y is zero, and x isn't, clearly y has the smaller payload.
669 if (y_is_zero) {
670 res = ((x & MASK_SIGN) == MASK_SIGN);
671 BID_RETURN (res);
673 // REDUNDANT REPRESENTATIONS (CASE6)
674 // if both components are either bigger or smaller,
675 // it is clear what needs to be done
676 if (sig_x > sig_y && exp_x >= exp_y) {
677 res = ((x & MASK_SIGN) == MASK_SIGN);
678 BID_RETURN (res);
680 if (sig_x < sig_y && exp_x <= exp_y) {
681 res = ((x & MASK_SIGN) != MASK_SIGN);
682 BID_RETURN (res);
684 // if exp_x is 15 greater than exp_y, it is
685 // definitely larger, so no need for compensation
686 if (exp_x - exp_y > 15) {
687 // difference cannot be greater than 10^15
688 res = ((x & MASK_SIGN) == MASK_SIGN);
689 BID_RETURN (res);
691 // if exp_x is 15 less than exp_y, it is
692 // definitely smaller, no need for compensation
693 if (exp_y - exp_x > 15) {
694 res = ((x & MASK_SIGN) != MASK_SIGN);
695 BID_RETURN (res);
697 // if |exp_x - exp_y| < 15, it comes down
698 // to the compensated significand
699 if (exp_x > exp_y) {
700 // otherwise adjust the x significand upwards
701 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
702 mult_factor[exp_x - exp_y]);
703 // if x and y represent the same entities,
704 // and both are negative, return true iff exp_x <= exp_y
705 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
706 // case cannot occure, because all bits must
707 // be the same - would have been caught if (x==y)
708 res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
709 BID_RETURN (res);
711 // if positive, return 1 if adjusted x is smaller than y
712 res = ((sig_n_prime.w[1] == 0)
713 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) ==
714 MASK_SIGN);
715 BID_RETURN (res);
717 // adjust the y significand upwards
718 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
719 mult_factor[exp_y - exp_x]);
721 // if x and y represent the same entities,
722 // and both are negative, return true iff exp_x <= exp_y
723 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
724 // Cannot occur, because all bits must be the same.
725 // Case would have been caught if (x==y)
726 res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
727 BID_RETURN (res);
729 // values are not equal, for positive numbers return 1
730 // if x is less than y. 0 otherwise
731 res = ((sig_n_prime.w[1] > 0)
732 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
733 MASK_SIGN);
734 BID_RETURN (res);
737 // totalOrderMag is TotalOrder(abs(x), abs(y))
738 #if DECIMAL_CALL_BY_REFERENCE
739 void
740 bid64_totalOrderMag (int *pres, UINT64 * px,
741 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
742 UINT64 x = *px;
743 UINT64 y = *py;
744 #else
746 bid64_totalOrderMag (UINT64 x,
747 UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
748 #endif
749 int res;
750 int exp_x, exp_y;
751 UINT64 sig_x, sig_y, pyld_y, pyld_x;
752 UINT128 sig_n_prime;
753 char x_is_zero = 0, y_is_zero = 0;
755 // NaN (CASE 1)
756 // if x and y are unordered numerically because either operand is NaN
757 // (1) totalOrder(number, +NaN) is true
758 // (2) if x and y are both NaN:
759 // i) signaling < quiet for +NaN
760 // ii) lesser payload < greater payload for +NaN
761 // iii) else if bitwise identical (in canonical form), return 1
762 if ((x & MASK_NAN) == MASK_NAN) {
763 // x is +NaN
765 // return false, unless y is +NaN also
766 if ((y & MASK_NAN) != MASK_NAN) {
767 res = 0; // y is a number, return 1
768 BID_RETURN (res);
770 } else {
772 // x and y are both +NaN;
773 // must investigate payload if both quiet or both signaling
774 // this xnor statement will be true if both x and y are +qNaN or +sNaN
775 if (!
776 (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
777 MASK_SNAN))) {
778 // it comes down to the payload. we want to return true if x has a
779 // smaller payload, or if the payloads are equal (canonical forms
780 // are bitwise identical)
781 pyld_y = y & 0x0003ffffffffffffull;
782 pyld_x = x & 0x0003ffffffffffffull;
783 // if x is zero and y isn't, x has the smaller
784 // payload definitely (since we know y isn't 0 at this point)
785 if (pyld_x > 999999999999999ull || pyld_x == 0) {
786 res = 1;
787 BID_RETURN (res);
790 if (pyld_y > 999999999999999ull || pyld_y == 0) {
791 // if y is zero, x must be less than or numerically equal
792 res = 0;
793 BID_RETURN (res);
795 res = (pyld_x <= pyld_y);
796 BID_RETURN (res);
798 } else {
799 // return true if y is +qNaN and x is +sNaN
800 // (we know they're different bc of xor if_stmt above)
801 res = ((x & MASK_SNAN) == MASK_SNAN);
802 BID_RETURN (res);
806 } else if ((y & MASK_NAN) == MASK_NAN) {
807 // x is certainly not NAN in this case.
808 // return true if y is positive
809 res = 1;
810 BID_RETURN (res);
812 // SIMPLE (CASE2)
813 // if all the bits (except sign bit) are the same,
814 // these numbers are equal.
815 if ((x & ~MASK_SIGN) == (y & ~MASK_SIGN)) {
816 res = 1;
817 BID_RETURN (res);
819 // INFINITY (CASE3)
820 if ((x & MASK_INF) == MASK_INF) {
821 // x is positive infinity, only return1
822 // if y is positive infinity as well
823 res = ((y & MASK_INF) == MASK_INF);
824 BID_RETURN (res);
825 } else if ((y & MASK_INF) == MASK_INF) {
826 // x is finite, so:
827 // if y is +inf, x<y
828 res = 1;
829 BID_RETURN (res);
831 // if steering bits are 11 (condition will be 0),
832 // then exponent is G[0:w+1] =>
833 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
834 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
835 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
836 if (sig_x > 9999999999999999ull || sig_x == 0) {
837 x_is_zero = 1;
839 } else {
840 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
841 sig_x = (x & MASK_BINARY_SIG1);
842 if (sig_x == 0) {
843 x_is_zero = 1;
847 // if steering bits are 11 (condition will be 0),
848 // then exponent is G[0:w+1] =>
849 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
850 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
851 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
852 if (sig_y > 9999999999999999ull || sig_y == 0) {
853 y_is_zero = 1;
855 } else {
856 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
857 sig_y = (y & MASK_BINARY_SIG1);
858 if (sig_y == 0) {
859 y_is_zero = 1;
863 // ZERO (CASE 5)
864 // if x and y represent the same entities,
865 // and both are negative , return true iff exp_x <= exp_y
866 if (x_is_zero && y_is_zero) {
867 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
868 res = (exp_x <= exp_y);
869 BID_RETURN (res);
871 // if x is zero and y isn't, clearly x has the smaller payload.
872 if (x_is_zero) {
873 res = 1;
874 BID_RETURN (res);
876 // if y is zero, and x isn't, clearly y has the smaller payload.
877 if (y_is_zero) {
878 res = 0;
879 BID_RETURN (res);
881 // REDUNDANT REPRESENTATIONS (CASE6)
882 // if both components are either bigger or smaller
883 if (sig_x > sig_y && exp_x >= exp_y) {
884 res = 0;
885 BID_RETURN (res);
887 if (sig_x < sig_y && exp_x <= exp_y) {
888 res = 1;
889 BID_RETURN (res);
891 // if exp_x is 15 greater than exp_y, it is definitely
892 // larger, so no need for compensation
893 if (exp_x - exp_y > 15) {
894 res = 0; // difference cannot be greater than 10^15
895 BID_RETURN (res);
897 // if exp_x is 15 less than exp_y, it is definitely
898 // smaller, no need for compensation
899 if (exp_y - exp_x > 15) {
900 res = 1;
901 BID_RETURN (res);
903 // if |exp_x - exp_y| < 15, it comes down
904 // to the compensated significand
905 if (exp_x > exp_y) {
907 // otherwise adjust the x significand upwards
908 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
909 mult_factor[exp_x - exp_y]);
911 // if x and y represent the same entities,
912 // and both are negative, return true iff exp_x <= exp_y
913 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
914 // case cannot occur, because all bits
915 // must be the same - would have been caught if (x==y)
916 res = (exp_x <= exp_y);
917 BID_RETURN (res);
919 // if positive, return 1 if adjusted x is smaller than y
920 res = ((sig_n_prime.w[1] == 0) && sig_n_prime.w[0] < sig_y);
921 BID_RETURN (res);
923 // adjust the y significand upwards
924 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
925 mult_factor[exp_y - exp_x]);
927 // if x and y represent the same entities,
928 // and both are negative, return true iff exp_x <= exp_y
929 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
930 res = (exp_x <= exp_y);
931 BID_RETURN (res);
933 // values are not equal, for positive numbers
934 // return 1 if x is less than y. 0 otherwise
935 res = ((sig_n_prime.w[1] > 0) || (sig_x < sig_n_prime.w[0]));
936 BID_RETURN (res);
940 #if DECIMAL_CALL_BY_REFERENCE
941 void
942 bid64_radix (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
943 UINT64 x = *px;
944 #else
946 bid64_radix (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
947 #endif
948 int res;
949 if (x) // dummy test
950 res = 10;
951 else
952 res = 10;
953 BID_RETURN (res);