Merge -r 127928:132243 from trunk
[official-gcc.git] / libgcc / config / libbid / bid64_noncomp.c
bloba811c6fa61e2b09af3d75b5f3f00d7286f72f1c7
1 /* Copyright (C) 2007 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version.
10 In addition to the permissions in the GNU General Public License, the
11 Free Software Foundation gives you unlimited permission to link the
12 compiled version of this file into combinations with other programs,
13 and to distribute those combinations without any restriction coming
14 from the use of this file. (The General Public License restrictions
15 do apply in other respects; for example, they cover modification of
16 the file, and distribution when not linked into a combine
17 executable.)
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING. If not, write to the Free
26 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
27 02110-1301, USA. */
29 #include "bid_internal.h"
31 static const UINT64 mult_factor[16] = {
32 1ull, 10ull, 100ull, 1000ull,
33 10000ull, 100000ull, 1000000ull, 10000000ull,
34 100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
35 1000000000000ull, 10000000000000ull,
36 100000000000000ull, 1000000000000000ull
39 /*****************************************************************************
40 * BID64 non-computational functions:
41 * - bid64_isSigned
42 * - bid64_isNormal
43 * - bid64_isSubnormal
44 * - bid64_isFinite
45 * - bid64_isZero
46 * - bid64_isInf
47 * - bid64_isSignaling
48 * - bid64_isCanonical
49 * - bid64_isNaN
50 * - bid64_copy
51 * - bid64_negate
52 * - bid64_abs
53 * - bid64_copySign
54 * - bid64_class
55 * - bid64_sameQuantum
56 * - bid64_totalOrder
57 * - bid64_totalOrderMag
58 * - bid64_radix
59 ****************************************************************************/
61 #if DECIMAL_CALL_BY_REFERENCE
62 void
63 bid64_isSigned (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
64 UINT64 x = *px;
65 #else
66 int
67 bid64_isSigned (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
68 #endif
69 int res;
71 res = ((x & MASK_SIGN) == MASK_SIGN);
72 BID_RETURN (res);
75 // return 1 iff x is not zero, nor NaN nor subnormal nor infinity
76 #if DECIMAL_CALL_BY_REFERENCE
77 void
78 bid64_isNormal (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
79 UINT64 x = *px;
80 #else
81 int
82 bid64_isNormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
83 #endif
84 int res;
85 UINT128 sig_x_prime;
86 UINT64 sig_x;
87 unsigned int exp_x;
89 if ((x & MASK_INF) == MASK_INF) { // x is either INF or NaN
90 res = 0;
91 } else {
92 // decode number into exponent and significand
93 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
94 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
95 // check for zero or non-canonical
96 if (sig_x > 9999999999999999ull || sig_x == 0) {
97 res = 0; // zero or non-canonical
98 BID_RETURN (res);
100 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
101 } else {
102 sig_x = (x & MASK_BINARY_SIG1);
103 if (sig_x == 0) {
104 res = 0; // zero
105 BID_RETURN (res);
107 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
109 // if exponent is less than -383, the number may be subnormal
110 // if (exp_x - 398 = -383) the number may be subnormal
111 if (exp_x < 15) {
112 __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
113 if (sig_x_prime.w[1] == 0
114 && sig_x_prime.w[0] < 1000000000000000ull) {
115 res = 0; // subnormal
116 } else {
117 res = 1; // normal
119 } else {
120 res = 1; // normal
123 BID_RETURN (res);
126 // return 1 iff x is not zero, nor NaN nor normal nor infinity
127 #if DECIMAL_CALL_BY_REFERENCE
128 void
129 bid64_isSubnormal (int *pres,
130 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
131 UINT64 x = *px;
132 #else
134 bid64_isSubnormal (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
135 #endif
136 int res;
137 UINT128 sig_x_prime;
138 UINT64 sig_x;
139 unsigned int exp_x;
141 if ((x & MASK_INF) == MASK_INF) { // x is either INF or NaN
142 res = 0;
143 } else {
144 // decode number into exponent and significand
145 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
146 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
147 // check for zero or non-canonical
148 if (sig_x > 9999999999999999ull || sig_x == 0) {
149 res = 0; // zero or non-canonical
150 BID_RETURN (res);
152 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
153 } else {
154 sig_x = (x & MASK_BINARY_SIG1);
155 if (sig_x == 0) {
156 res = 0; // zero
157 BID_RETURN (res);
159 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
161 // if exponent is less than -383, the number may be subnormal
162 // if (exp_x - 398 = -383) the number may be subnormal
163 if (exp_x < 15) {
164 __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
165 if (sig_x_prime.w[1] == 0
166 && sig_x_prime.w[0] < 1000000000000000ull) {
167 res = 1; // subnormal
168 } else {
169 res = 0; // normal
171 } else {
172 res = 0; // normal
175 BID_RETURN (res);
178 //iff x is zero, subnormal or normal (not infinity or NaN)
179 #if DECIMAL_CALL_BY_REFERENCE
180 void
181 bid64_isFinite (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
182 UINT64 x = *px;
183 #else
185 bid64_isFinite (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
186 #endif
187 int res;
189 res = ((x & MASK_INF) != MASK_INF);
190 BID_RETURN (res);
193 #if DECIMAL_CALL_BY_REFERENCE
194 void
195 bid64_isZero (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
196 UINT64 x = *px;
197 #else
199 bid64_isZero (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
200 #endif
201 int res;
203 // if infinity or nan, return 0
204 if ((x & MASK_INF) == MASK_INF) {
205 res = 0;
206 } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
207 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1]
208 // => sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
209 // if(sig_x > 9999999999999999ull) {return 1;}
210 res =
211 (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
212 9999999999999999ull);
213 } else {
214 res = ((x & MASK_BINARY_SIG1) == 0);
216 BID_RETURN (res);
219 #if DECIMAL_CALL_BY_REFERENCE
220 void
221 bid64_isInf (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
222 UINT64 x = *px;
223 #else
225 bid64_isInf (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
226 #endif
227 int res;
229 res = ((x & MASK_INF) == MASK_INF) && ((x & MASK_NAN) != MASK_NAN);
230 BID_RETURN (res);
233 #if DECIMAL_CALL_BY_REFERENCE
234 void
235 bid64_isSignaling (int *pres,
236 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
237 UINT64 x = *px;
238 #else
240 bid64_isSignaling (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
241 #endif
242 int res;
244 res = ((x & MASK_SNAN) == MASK_SNAN);
245 BID_RETURN (res);
248 #if DECIMAL_CALL_BY_REFERENCE
249 void
250 bid64_isCanonical (int *pres,
251 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
252 UINT64 x = *px;
253 #else
255 bid64_isCanonical (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
256 #endif
257 int res;
259 if ((x & MASK_NAN) == MASK_NAN) { // NaN
260 if (x & 0x01fc000000000000ull) {
261 res = 0;
262 } else if ((x & 0x0003ffffffffffffull) > 999999999999999ull) { // payload
263 res = 0;
264 } else {
265 res = 1;
267 } else if ((x & MASK_INF) == MASK_INF) {
268 if (x & 0x03ffffffffffffffull) {
269 res = 0;
270 } else {
271 res = 1;
273 } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // 54-bit coeff.
274 res =
275 (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) <=
276 9999999999999999ull);
277 } else { // 53-bit coeff.
278 res = 1;
280 BID_RETURN (res);
283 #if DECIMAL_CALL_BY_REFERENCE
284 void
285 bid64_isNaN (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
286 UINT64 x = *px;
287 #else
289 bid64_isNaN (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
290 #endif
291 int res;
293 res = ((x & MASK_NAN) == MASK_NAN);
294 BID_RETURN (res);
297 // copies a floating-point operand x to destination y, with no change
298 #if DECIMAL_CALL_BY_REFERENCE
299 void
300 bid64_copy (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
301 UINT64 x = *px;
302 #else
303 UINT64
304 bid64_copy (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
305 #endif
306 UINT64 res;
308 res = x;
309 BID_RETURN (res);
312 // copies a floating-point operand x to destination y, reversing the sign
313 #if DECIMAL_CALL_BY_REFERENCE
314 void
315 bid64_negate (UINT64 * pres,
316 UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
317 UINT64 x = *px;
318 #else
319 UINT64
320 bid64_negate (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
321 #endif
322 UINT64 res;
324 res = x ^ MASK_SIGN;
325 BID_RETURN (res);
328 // copies a floating-point operand x to destination y, changing the sign to positive
329 #if DECIMAL_CALL_BY_REFERENCE
330 void
331 bid64_abs (UINT64 * pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
332 UINT64 x = *px;
333 #else
334 UINT64
335 bid64_abs (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
336 #endif
337 UINT64 res;
339 res = x & ~MASK_SIGN;
340 BID_RETURN (res);
343 // copies operand x to destination in the same format as x, but
344 // with the sign of y
345 #if DECIMAL_CALL_BY_REFERENCE
346 void
347 bid64_copySign (UINT64 * pres, UINT64 * px,
348 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
349 UINT64 x = *px;
350 UINT64 y = *py;
351 #else
352 UINT64
353 bid64_copySign (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
354 #endif
355 UINT64 res;
357 res = (x & ~MASK_SIGN) | (y & MASK_SIGN);
358 BID_RETURN (res);
361 #if DECIMAL_CALL_BY_REFERENCE
362 void
363 bid64_class (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
364 UINT64 x = *px;
365 #else
367 bid64_class (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
368 #endif
369 int res;
370 UINT128 sig_x_prime;
371 UINT64 sig_x;
372 int exp_x;
374 if ((x & MASK_NAN) == MASK_NAN) {
375 // is the NaN signaling?
376 if ((x & MASK_SNAN) == MASK_SNAN) {
377 res = signalingNaN;
378 BID_RETURN (res);
380 // if NaN and not signaling, must be quietNaN
381 res = quietNaN;
382 BID_RETURN (res);
383 } else if ((x & MASK_INF) == MASK_INF) {
384 // is the Infinity negative?
385 if ((x & MASK_SIGN) == MASK_SIGN) {
386 res = negativeInfinity;
387 } else {
388 // otherwise, must be positive infinity
389 res = positiveInfinity;
391 BID_RETURN (res);
392 } else if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
393 // decode number into exponent and significand
394 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
395 // check for zero or non-canonical
396 if (sig_x > 9999999999999999ull || sig_x == 0) {
397 if ((x & MASK_SIGN) == MASK_SIGN) {
398 res = negativeZero;
399 } else {
400 res = positiveZero;
402 BID_RETURN (res);
404 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
405 } else {
406 sig_x = (x & MASK_BINARY_SIG1);
407 if (sig_x == 0) {
408 res =
409 ((x & MASK_SIGN) == MASK_SIGN) ? negativeZero : positiveZero;
410 BID_RETURN (res);
412 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
414 // if exponent is less than -383, number may be subnormal
415 // if (exp_x - 398 < -383)
416 if (exp_x < 15) { // sig_x *10^exp_x
417 __mul_64x64_to_128MACH (sig_x_prime, sig_x, mult_factor[exp_x]);
418 if (sig_x_prime.w[1] == 0
419 && (sig_x_prime.w[0] < 1000000000000000ull)) {
420 res =
421 ((x & MASK_SIGN) ==
422 MASK_SIGN) ? negativeSubnormal : positiveSubnormal;
423 BID_RETURN (res);
426 // otherwise, normal number, determine the sign
427 res =
428 ((x & MASK_SIGN) == MASK_SIGN) ? negativeNormal : positiveNormal;
429 BID_RETURN (res);
432 // true if the exponents of x and y are the same, false otherwise.
433 // The special cases of sameQuantum (NaN, NaN) and sameQuantum (Inf, Inf) are
434 // true.
435 // If exactly one operand is infinite or exactly one operand is NaN, then false
436 #if DECIMAL_CALL_BY_REFERENCE
437 void
438 bid64_sameQuantum (int *pres, UINT64 * px,
439 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
440 UINT64 x = *px;
441 UINT64 y = *py;
442 #else
444 bid64_sameQuantum (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
445 #endif
446 int res;
447 unsigned int exp_x, exp_y;
449 // if both operands are NaN, return true; if just one is NaN, return false
450 if ((x & MASK_NAN) == MASK_NAN || ((y & MASK_NAN) == MASK_NAN)) {
451 res = ((x & MASK_NAN) == MASK_NAN && (y & MASK_NAN) == MASK_NAN);
452 BID_RETURN (res);
454 // if both operands are INF, return true; if just one is INF, return false
455 if ((x & MASK_INF) == MASK_INF || (y & MASK_INF) == MASK_INF) {
456 res = ((x & MASK_INF) == MASK_INF && (y & MASK_INF) == MASK_INF);
457 BID_RETURN (res);
459 // decode exponents for both numbers, and return true if they match
460 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
461 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
462 } else {
463 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
465 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
466 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
467 } else {
468 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
470 res = (exp_x == exp_y);
471 BID_RETURN (res);
474 #if DECIMAL_CALL_BY_REFERENCE
475 void
476 bid64_totalOrder (int *pres, UINT64 * px,
477 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
478 UINT64 x = *px;
479 UINT64 y = *py;
480 #else
482 bid64_totalOrder (UINT64 x, UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
483 #endif
484 int res;
485 int exp_x, exp_y;
486 UINT64 sig_x, sig_y, pyld_y, pyld_x;
487 UINT128 sig_n_prime;
488 char x_is_zero = 0, y_is_zero = 0;
490 // NaN (CASE1)
491 // if x and y are unordered numerically because either operand is NaN
492 // (1) totalOrder(-NaN, number) is true
493 // (2) totalOrder(number, +NaN) is true
494 // (3) if x and y are both NaN:
495 // i) negative sign bit < positive sign bit
496 // ii) signaling < quiet for +NaN, reverse for -NaN
497 // iii) lesser payload < greater payload for +NaN (reverse for -NaN)
498 // iv) else if bitwise identical (in canonical form), return 1
499 if ((x & MASK_NAN) == MASK_NAN) {
500 // if x is -NaN
501 if ((x & MASK_SIGN) == MASK_SIGN) {
502 // return true, unless y is -NaN also
503 if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) != MASK_SIGN) {
504 res = 1; // y is a number, return 1
505 BID_RETURN (res);
506 } else { // if y and x are both -NaN
507 // if x and y are both -sNaN or both -qNaN, we have to compare payloads
508 // this xnor statement evaluates to true if both are sNaN or qNaN
509 if (!
510 (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
511 MASK_SNAN))) {
512 // it comes down to the payload. we want to return true if x has a
513 // larger payload, or if the payloads are equal (canonical forms
514 // are bitwise identical)
515 pyld_y = y & 0x0003ffffffffffffull;
516 pyld_x = x & 0x0003ffffffffffffull;
517 if (pyld_y > 999999999999999ull || pyld_y == 0) {
518 // if y is zero, x must be less than or numerically equal
519 // y's payload is 0
520 res = 1;
521 BID_RETURN (res);
523 // if x is zero and y isn't, x has the smaller payload
524 // definitely (since we know y isn't 0 at this point)
525 if (pyld_x > 999999999999999ull || pyld_x == 0) {
526 // x's payload is 0
527 res = 0;
528 BID_RETURN (res);
530 res = (pyld_x >= pyld_y);
531 BID_RETURN (res);
532 } else {
533 // either x = -sNaN and y = -qNaN or x = -qNaN and y = -sNaN
534 res = (y & MASK_SNAN) == MASK_SNAN; // totalOrder(-qNaN, -sNaN) == 1
535 BID_RETURN (res);
538 } else { // x is +NaN
539 // return false, unless y is +NaN also
540 if ((y & MASK_NAN) != MASK_NAN || (y & MASK_SIGN) == MASK_SIGN) {
541 res = 0; // y is a number, return 1
542 BID_RETURN (res);
543 } else {
544 // x and y are both +NaN;
545 // must investigate payload if both quiet or both signaling
546 // this xnor statement will be true if both x and y are +qNaN or +sNaN
547 if (!
548 (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
549 MASK_SNAN))) {
550 // it comes down to the payload. we want to return true if x has a
551 // smaller payload, or if the payloads are equal (canonical forms
552 // are bitwise identical)
553 pyld_y = y & 0x0003ffffffffffffull;
554 pyld_x = x & 0x0003ffffffffffffull;
555 // if x is zero and y isn't, x has the smaller
556 // payload definitely (since we know y isn't 0 at this point)
557 if (pyld_x > 999999999999999ull || pyld_x == 0) {
558 res = 1;
559 BID_RETURN (res);
561 if (pyld_y > 999999999999999ull || pyld_y == 0) {
562 // if y is zero, x must be less than or numerically equal
563 res = 0;
564 BID_RETURN (res);
566 res = (pyld_x <= pyld_y);
567 BID_RETURN (res);
568 } else {
569 // return true if y is +qNaN and x is +sNaN
570 // (we know they're different bc of xor if_stmt above)
571 res = ((x & MASK_SNAN) == MASK_SNAN);
572 BID_RETURN (res);
576 } else if ((y & MASK_NAN) == MASK_NAN) {
577 // x is certainly not NAN in this case.
578 // return true if y is positive
579 res = ((y & MASK_SIGN) != MASK_SIGN);
580 BID_RETURN (res);
582 // SIMPLE (CASE2)
583 // if all the bits are the same, these numbers are equal.
584 if (x == y) {
585 res = 1;
586 BID_RETURN (res);
588 // OPPOSITE SIGNS (CASE 3)
589 // if signs are opposite, return 1 if x is negative
590 // (if x<y, totalOrder is true)
591 if (((x & MASK_SIGN) == MASK_SIGN) ^ ((y & MASK_SIGN) == MASK_SIGN)) {
592 res = (x & MASK_SIGN) == MASK_SIGN;
593 BID_RETURN (res);
595 // INFINITY (CASE4)
596 if ((x & MASK_INF) == MASK_INF) {
597 // if x==neg_inf, return (y == neg_inf)?1:0;
598 if ((x & MASK_SIGN) == MASK_SIGN) {
599 res = 1;
600 BID_RETURN (res);
601 } else {
602 // x is positive infinity, only return1 if y
603 // is positive infinity as well
604 // (we know y has same sign as x)
605 res = ((y & MASK_INF) == MASK_INF);
606 BID_RETURN (res);
608 } else if ((y & MASK_INF) == MASK_INF) {
609 // x is finite, so:
610 // if y is +inf, x<y
611 // if y is -inf, x>y
612 res = ((y & MASK_SIGN) != MASK_SIGN);
613 BID_RETURN (res);
615 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
616 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
617 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
618 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
619 if (sig_x > 9999999999999999ull || sig_x == 0) {
620 x_is_zero = 1;
622 } else {
623 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
624 sig_x = (x & MASK_BINARY_SIG1);
625 if (sig_x == 0) {
626 x_is_zero = 1;
630 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
631 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
632 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
633 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
634 if (sig_y > 9999999999999999ull || sig_y == 0) {
635 y_is_zero = 1;
637 } else {
638 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
639 sig_y = (y & MASK_BINARY_SIG1);
640 if (sig_y == 0) {
641 y_is_zero = 1;
645 // ZERO (CASE 5)
646 // if x and y represent the same entities, and
647 // both are negative , return true iff exp_x <= exp_y
648 if (x_is_zero && y_is_zero) {
649 if (!((x & MASK_SIGN) == MASK_SIGN) ^
650 ((y & MASK_SIGN) == MASK_SIGN)) {
651 // if signs are the same:
652 // totalOrder(x,y) iff exp_x >= exp_y for negative numbers
653 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
654 if (exp_x == exp_y) {
655 res = 1;
656 BID_RETURN (res);
658 res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
659 BID_RETURN (res);
660 } else {
661 // signs are different.
662 // totalOrder(-0, +0) is true
663 // totalOrder(+0, -0) is false
664 res = ((x & MASK_SIGN) == MASK_SIGN);
665 BID_RETURN (res);
668 // if x is zero and y isn't, clearly x has the smaller payload.
669 if (x_is_zero) {
670 res = ((y & MASK_SIGN) != MASK_SIGN);
671 BID_RETURN (res);
673 // if y is zero, and x isn't, clearly y has the smaller payload.
674 if (y_is_zero) {
675 res = ((x & MASK_SIGN) == MASK_SIGN);
676 BID_RETURN (res);
678 // REDUNDANT REPRESENTATIONS (CASE6)
679 // if both components are either bigger or smaller,
680 // it is clear what needs to be done
681 if (sig_x > sig_y && exp_x >= exp_y) {
682 res = ((x & MASK_SIGN) == MASK_SIGN);
683 BID_RETURN (res);
685 if (sig_x < sig_y && exp_x <= exp_y) {
686 res = ((x & MASK_SIGN) != MASK_SIGN);
687 BID_RETURN (res);
689 // if exp_x is 15 greater than exp_y, it is
690 // definitely larger, so no need for compensation
691 if (exp_x - exp_y > 15) {
692 // difference cannot be greater than 10^15
693 res = ((x & MASK_SIGN) == MASK_SIGN);
694 BID_RETURN (res);
696 // if exp_x is 15 less than exp_y, it is
697 // definitely smaller, no need for compensation
698 if (exp_y - exp_x > 15) {
699 res = ((x & MASK_SIGN) != MASK_SIGN);
700 BID_RETURN (res);
702 // if |exp_x - exp_y| < 15, it comes down
703 // to the compensated significand
704 if (exp_x > exp_y) {
705 // otherwise adjust the x significand upwards
706 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
707 mult_factor[exp_x - exp_y]);
708 // if x and y represent the same entities,
709 // and both are negative, return true iff exp_x <= exp_y
710 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
711 // case cannot occure, because all bits must
712 // be the same - would have been caught if (x==y)
713 res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
714 BID_RETURN (res);
716 // if positive, return 1 if adjusted x is smaller than y
717 res = ((sig_n_prime.w[1] == 0)
718 && sig_n_prime.w[0] < sig_y) ^ ((x & MASK_SIGN) ==
719 MASK_SIGN);
720 BID_RETURN (res);
722 // adjust the y significand upwards
723 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
724 mult_factor[exp_y - exp_x]);
726 // if x and y represent the same entities,
727 // and both are negative, return true iff exp_x <= exp_y
728 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
729 // Cannot occur, because all bits must be the same.
730 // Case would have been caught if (x==y)
731 res = (exp_x <= exp_y) ^ ((x & MASK_SIGN) == MASK_SIGN);
732 BID_RETURN (res);
734 // values are not equal, for positive numbers return 1
735 // if x is less than y. 0 otherwise
736 res = ((sig_n_prime.w[1] > 0)
737 || (sig_x < sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
738 MASK_SIGN);
739 BID_RETURN (res);
742 // totalOrderMag is TotalOrder(abs(x), abs(y))
743 #if DECIMAL_CALL_BY_REFERENCE
744 void
745 bid64_totalOrderMag (int *pres, UINT64 * px,
746 UINT64 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
747 UINT64 x = *px;
748 UINT64 y = *py;
749 #else
751 bid64_totalOrderMag (UINT64 x,
752 UINT64 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
753 #endif
754 int res;
755 int exp_x, exp_y;
756 UINT64 sig_x, sig_y, pyld_y, pyld_x;
757 UINT128 sig_n_prime;
758 char x_is_zero = 0, y_is_zero = 0;
760 // NaN (CASE 1)
761 // if x and y are unordered numerically because either operand is NaN
762 // (1) totalOrder(number, +NaN) is true
763 // (2) if x and y are both NaN:
764 // i) signaling < quiet for +NaN
765 // ii) lesser payload < greater payload for +NaN
766 // iii) else if bitwise identical (in canonical form), return 1
767 if ((x & MASK_NAN) == MASK_NAN) {
768 // x is +NaN
770 // return false, unless y is +NaN also
771 if ((y & MASK_NAN) != MASK_NAN) {
772 res = 0; // y is a number, return 1
773 BID_RETURN (res);
775 } else {
777 // x and y are both +NaN;
778 // must investigate payload if both quiet or both signaling
779 // this xnor statement will be true if both x and y are +qNaN or +sNaN
780 if (!
781 (((y & MASK_SNAN) == MASK_SNAN) ^ ((x & MASK_SNAN) ==
782 MASK_SNAN))) {
783 // it comes down to the payload. we want to return true if x has a
784 // smaller payload, or if the payloads are equal (canonical forms
785 // are bitwise identical)
786 pyld_y = y & 0x0003ffffffffffffull;
787 pyld_x = x & 0x0003ffffffffffffull;
788 // if x is zero and y isn't, x has the smaller
789 // payload definitely (since we know y isn't 0 at this point)
790 if (pyld_x > 999999999999999ull || pyld_x == 0) {
791 res = 1;
792 BID_RETURN (res);
795 if (pyld_y > 999999999999999ull || pyld_y == 0) {
796 // if y is zero, x must be less than or numerically equal
797 res = 0;
798 BID_RETURN (res);
800 res = (pyld_x <= pyld_y);
801 BID_RETURN (res);
803 } else {
804 // return true if y is +qNaN and x is +sNaN
805 // (we know they're different bc of xor if_stmt above)
806 res = ((x & MASK_SNAN) == MASK_SNAN);
807 BID_RETURN (res);
811 } else if ((y & MASK_NAN) == MASK_NAN) {
812 // x is certainly not NAN in this case.
813 // return true if y is positive
814 res = 1;
815 BID_RETURN (res);
817 // SIMPLE (CASE2)
818 // if all the bits (except sign bit) are the same,
819 // these numbers are equal.
820 if ((x & ~MASK_SIGN) == (y & ~MASK_SIGN)) {
821 res = 1;
822 BID_RETURN (res);
824 // INFINITY (CASE3)
825 if ((x & MASK_INF) == MASK_INF) {
826 // x is positive infinity, only return1
827 // if y is positive infinity as well
828 res = ((y & MASK_INF) == MASK_INF);
829 BID_RETURN (res);
830 } else if ((y & MASK_INF) == MASK_INF) {
831 // x is finite, so:
832 // if y is +inf, x<y
833 res = 1;
834 BID_RETURN (res);
836 // if steering bits are 11 (condition will be 0),
837 // then exponent is G[0:w+1] =>
838 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
839 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
840 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
841 if (sig_x > 9999999999999999ull || sig_x == 0) {
842 x_is_zero = 1;
844 } else {
845 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
846 sig_x = (x & MASK_BINARY_SIG1);
847 if (sig_x == 0) {
848 x_is_zero = 1;
852 // if steering bits are 11 (condition will be 0),
853 // then exponent is G[0:w+1] =>
854 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
855 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
856 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
857 if (sig_y > 9999999999999999ull || sig_y == 0) {
858 y_is_zero = 1;
860 } else {
861 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
862 sig_y = (y & MASK_BINARY_SIG1);
863 if (sig_y == 0) {
864 y_is_zero = 1;
868 // ZERO (CASE 5)
869 // if x and y represent the same entities,
870 // and both are negative , return true iff exp_x <= exp_y
871 if (x_is_zero && y_is_zero) {
872 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers
873 res = (exp_x <= exp_y);
874 BID_RETURN (res);
876 // if x is zero and y isn't, clearly x has the smaller payload.
877 if (x_is_zero) {
878 res = 1;
879 BID_RETURN (res);
881 // if y is zero, and x isn't, clearly y has the smaller payload.
882 if (y_is_zero) {
883 res = 0;
884 BID_RETURN (res);
886 // REDUNDANT REPRESENTATIONS (CASE6)
887 // if both components are either bigger or smaller
888 if (sig_x > sig_y && exp_x >= exp_y) {
889 res = 0;
890 BID_RETURN (res);
892 if (sig_x < sig_y && exp_x <= exp_y) {
893 res = 1;
894 BID_RETURN (res);
896 // if exp_x is 15 greater than exp_y, it is definitely
897 // larger, so no need for compensation
898 if (exp_x - exp_y > 15) {
899 res = 0; // difference cannot be greater than 10^15
900 BID_RETURN (res);
902 // if exp_x is 15 less than exp_y, it is definitely
903 // smaller, no need for compensation
904 if (exp_y - exp_x > 15) {
905 res = 1;
906 BID_RETURN (res);
908 // if |exp_x - exp_y| < 15, it comes down
909 // to the compensated significand
910 if (exp_x > exp_y) {
912 // otherwise adjust the x significand upwards
913 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
914 mult_factor[exp_x - exp_y]);
916 // if x and y represent the same entities,
917 // and both are negative, return true iff exp_x <= exp_y
918 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
919 // case cannot occur, because all bits
920 // must be the same - would have been caught if (x==y)
921 res = (exp_x <= exp_y);
922 BID_RETURN (res);
924 // if positive, return 1 if adjusted x is smaller than y
925 res = ((sig_n_prime.w[1] == 0) && sig_n_prime.w[0] < sig_y);
926 BID_RETURN (res);
928 // adjust the y significand upwards
929 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
930 mult_factor[exp_y - exp_x]);
932 // if x and y represent the same entities,
933 // and both are negative, return true iff exp_x <= exp_y
934 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
935 res = (exp_x <= exp_y);
936 BID_RETURN (res);
938 // values are not equal, for positive numbers
939 // return 1 if x is less than y. 0 otherwise
940 res = ((sig_n_prime.w[1] > 0) || (sig_x < sig_n_prime.w[0]));
941 BID_RETURN (res);
945 #if DECIMAL_CALL_BY_REFERENCE
946 void
947 bid64_radix (int *pres, UINT64 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
948 UINT64 x = *px;
949 #else
951 bid64_radix (UINT64 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
952 #endif
953 int res;
954 if (x) // dummy test
955 res = 10;
956 else
957 res = 10;
958 BID_RETURN (res);