]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/libbid/bid128_minmax.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_minmax.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#define BID_128RES
30#include "bid_internal.h"
31
32/*****************************************************************************
33 * BID128 minimum number
34 *****************************************************************************/
35
36#if DECIMAL_CALL_BY_REFERENCE
37void
b2a00c89
L
38bid128_minnum (UINT128 * pres, UINT128 * px,
39 UINT128 * py _EXC_FLAGS_PARAM) {
200359e8
L
40 UINT128 x = *px;
41 UINT128 y = *py;
42#else
43UINT128
b2a00c89 44bid128_minnum (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
200359e8
L
45#endif
46
47 UINT128 res;
48 int exp_x, exp_y;
49 int diff;
50 UINT128 sig_x, sig_y;
51 UINT192 sig_n_prime192;
52 UINT256 sig_n_prime256;
b2a00c89 53 char x_is_zero = 0, y_is_zero = 0;
200359e8 54
b2a00c89
L
55 BID_SWAP128 (x);
56 BID_SWAP128 (y);
57
58 // check for non-canonical x
59 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
60 x.w[1] = x.w[1] & 0xfe003fffffffffffull; // clear out G[6]-G[16]
61 // check for non-canonical NaN payload
62 if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
63 (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
64 (x.w[0] > 0x38c15b09ffffffffull))) {
65 x.w[1] = x.w[1] & 0xffffc00000000000ull;
66 x.w[0] = 0x0ull;
200359e8 67 }
b2a00c89
L
68 } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) { // x = inf
69 x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
70 x.w[0] = 0x0ull;
71 } else { // x is not special
72 // check for non-canonical values - treated as zero
73 if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // G0_G1=11
74 // non-canonical
75 x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
76 x.w[0] = 0x0ull;
77 } else { // G0_G1 != 11
78 if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
79 ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
80 && x.w[0] > 0x378d8e63ffffffffull)) {
81 // x is non-canonical if coefficient is larger than 10^34 -1
82 x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
83 x.w[0] = 0x0ull;
84 } else { // canonical
85 ;
86 }
200359e8 87 }
200359e8 88 }
b2a00c89
L
89 // check for non-canonical y
90 if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
91 y.w[1] = y.w[1] & 0xfe003fffffffffffull; // clear out G[6]-G[16]
92 // check for non-canonical NaN payload
93 if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
94 (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
95 (y.w[0] > 0x38c15b09ffffffffull))) {
96 y.w[1] = y.w[1] & 0xffffc00000000000ull;
97 y.w[0] = 0x0ull;
98 }
99 } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) { // y = inf
100 y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
101 y.w[0] = 0x0ull;
102 } else { // y is not special
103 // check for non-canonical values - treated as zero
104 if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // G0_G1=11
105 // non-canonical
106 y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
107 y.w[0] = 0x0ull;
108 } else { // G0_G1 != 11
109 if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
110 ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
111 && y.w[0] > 0x378d8e63ffffffffull)) {
112 // y is non-canonical if coefficient is larger than 10^34 -1
113 y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
114 y.w[0] = 0x0ull;
115 } else { // canonical
116 ;
117 }
118 }
119 }
120
121 // NaN (CASE1)
122 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
123 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNaN
124 // if x is SNAN, then return quiet (x)
125 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
126 x.w[1] = x.w[1] & 0xfdffffffffffffffull; // quietize x
127 res = x;
128 } else { // x is QNaN
129 if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
130 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
131 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
132 }
133 res = x;
134 } else {
135 res = y;
136 }
137 }
138 BID_RETURN (res);
139 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
140 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
141 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
142 y.w[1] = y.w[1] & 0xfdffffffffffffffull; // quietize y
143 res = y;
144 } else {
145 // will return x (which is not NaN)
146 res = x;
200359e8 147 }
200359e8
L
148 BID_RETURN (res);
149 }
150 // SIMPLE (CASE2)
151 // if all the bits are the same, these numbers are equal (not Greater).
152 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
153 res = x;
154 BID_RETURN (res);
155 }
156 // INFINITY (CASE3)
157 if ((x.w[1] & MASK_INF) == MASK_INF) {
158 // if x is neg infinity, there is no way it is greater than y, return 0
159 res = (((x.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
160 BID_RETURN (res);
161 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
162 // x is finite, so if y is positive infinity, then x is less, return 0
163 // if y is negative infinity, then x is greater, return 1
164 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
165 BID_RETURN (res);
166 }
167 // CONVERT X
168 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
169 sig_x.w[0] = x.w[0];
170 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
171
200359e8
L
172 // CONVERT Y
173 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
174 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
175 sig_y.w[0] = y.w[0];
176
200359e8
L
177 // ZERO (CASE4)
178 // some properties:
179 // (+ZERO == -ZERO) => therefore ignore the sign
180 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B => ignore the exponent
181 // field
182 // (Any non-canonical # is considered 0)
b2a00c89 183 if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
200359e8
L
184 x_is_zero = 1;
185 }
b2a00c89 186 if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
200359e8
L
187 y_is_zero = 1;
188 }
189
190 if (x_is_zero && y_is_zero) {
191 // if both numbers are zero, neither is greater => return either number
192 res = x;
193 BID_RETURN (res);
194 } else if (x_is_zero) {
195 // is x is zero, it is greater if Y is negative
196 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
197 BID_RETURN (res);
198 } else if (y_is_zero) {
199 // is y is zero, X is greater if it is positive
200 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
201 BID_RETURN (res);
202 }
203 // OPPOSITE SIGN (CASE5)
204 // now, if the sign bits differ, x is greater if y is negative
205 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
206 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
207 BID_RETURN (res);
208 }
209 // REDUNDANT REPRESENTATIONS (CASE6)
210 // if exponents are the same, then we have a simple comparison of
211 // the significands
212 if (exp_y == exp_x) {
213 res = (((sig_x.w[1] > sig_y.w[1])
b2a00c89
L
214 || (sig_x.w[1] == sig_y.w[1]
215 && sig_x.w[0] >= sig_y.w[0])) ^ ((x.w[1] & MASK_SIGN) ==
216 MASK_SIGN)) ? y : x;
200359e8
L
217 BID_RETURN (res);
218 }
219 // if both components are either bigger or smaller, it is clear what
220 // needs to be done
221 if (sig_x.w[1] >= sig_y.w[1] && sig_x.w[0] >= sig_y.w[0]
222 && exp_x > exp_y) {
223 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
224 BID_RETURN (res);
225 }
226 if (sig_x.w[1] <= sig_y.w[1] && sig_x.w[0] <= sig_y.w[0]
227 && exp_x < exp_y) {
228 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
229 BID_RETURN (res);
230 }
231
232 diff = exp_x - exp_y;
233
234 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
b2a00c89 235 if (diff > 0) { // to simplify the loop below,
200359e8
L
236 // if exp_x is 33 greater than exp_y, no need for compensation
237 if (diff > 33) {
238 // difference cannot be greater than 10^33
239 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? y : x;
240 BID_RETURN (res);
241 }
b2a00c89
L
242 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
243 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
200359e8
L
244 // if postitive, return whichever significand is larger
245 // (converse if negative)
246 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
b2a00c89
L
247 || (sig_n_prime256.w[1] > sig_y.w[1])
248 || (sig_n_prime256.w[1] == sig_y.w[1]
249 && sig_n_prime256.w[0] >
250 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) ==
251 MASK_SIGN)) ? y : x;
200359e8
L
252 BID_RETURN (res);
253 }
b2a00c89 254 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
200359e8
L
255 // if postitive, return whichever significand is larger
256 // (converse if negative)
257 res =
258 (((sig_n_prime192.w[2] > 0) || (sig_n_prime192.w[1] > sig_y.w[1])
b2a00c89
L
259 || (sig_n_prime192.w[1] == sig_y.w[1]
260 && sig_n_prime192.w[0] >
261 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? y : x;
200359e8
L
262 BID_RETURN (res);
263 }
264 diff = exp_y - exp_x;
265 // if exp_x is 33 less than exp_y, no need for compensation
266 if (diff > 33) {
267 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
268 BID_RETURN (res);
269 }
b2a00c89 270 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
200359e8 271 // adjust the y significand upwards
b2a00c89 272 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
200359e8
L
273 // if postitive, return whichever significand is larger
274 // (converse if negative)
275 res =
276 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
b2a00c89
L
277 || (sig_n_prime256.w[1] > sig_x.w[1]
278 || (sig_n_prime256.w[1] == sig_x.w[1]
279 && sig_n_prime256.w[0] >
280 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) ==
281 MASK_SIGN)) ? x : y;
200359e8
L
282 BID_RETURN (res);
283 }
284 // adjust the y significand upwards
b2a00c89 285 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
200359e8 286 // if postitive, return whichever significand is larger (converse if negative)
b2a00c89
L
287 res =
288 ((sig_n_prime192.w[2] != 0
289 || (sig_n_prime192.w[1] > sig_x.w[1]
290 || (sig_n_prime192.w[1] == sig_x.w[1]
291 && sig_n_prime192.w[0] > sig_x.w[0])))
292 ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
200359e8
L
293 BID_RETURN (res);
294}
295
296/*****************************************************************************
297 * BID128 minimum magnitude function - returns greater of two numbers
298 *****************************************************************************/
299
300#if DECIMAL_CALL_BY_REFERENCE
301void
b2a00c89
L
302bid128_minnum_mag (UINT128 * pres, UINT128 * px,
303 UINT128 * py _EXC_FLAGS_PARAM) {
200359e8
L
304 UINT128 x = *px;
305 UINT128 y = *py;
306#else
307UINT128
b2a00c89 308bid128_minnum_mag (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
200359e8
L
309#endif
310
311 UINT128 res;
312 int exp_x, exp_y;
313 int diff;
314 UINT128 sig_x, sig_y;
315 UINT192 sig_n_prime192;
316 UINT256 sig_n_prime256;
200359e8 317
b2a00c89
L
318 BID_SWAP128 (x);
319 BID_SWAP128 (y);
320
321 // check for non-canonical x
322 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
323 x.w[1] = x.w[1] & 0xfe003fffffffffffull; // clear out G[6]-G[16]
324 // check for non-canonical NaN payload
325 if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
326 (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
327 (x.w[0] > 0x38c15b09ffffffffull))) {
328 x.w[1] = x.w[1] & 0xffffc00000000000ull;
329 x.w[0] = 0x0ull;
200359e8 330 }
b2a00c89
L
331 } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) { // x = inf
332 x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
333 x.w[0] = 0x0ull;
334 } else { // x is not special
335 // check for non-canonical values - treated as zero
336 if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // G0_G1=11
337 // non-canonical
338 x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
339 x.w[0] = 0x0ull;
340 } else { // G0_G1 != 11
341 if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
342 ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
343 && x.w[0] > 0x378d8e63ffffffffull)) {
344 // x is non-canonical if coefficient is larger than 10^34 -1
345 x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
346 x.w[0] = 0x0ull;
347 } else { // canonical
348 ;
349 }
350 }
351 }
352 // check for non-canonical y
353 if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
354 y.w[1] = y.w[1] & 0xfe003fffffffffffull; // clear out G[6]-G[16]
355 // check for non-canonical NaN payload
356 if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
357 (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
358 (y.w[0] > 0x38c15b09ffffffffull))) {
359 y.w[1] = y.w[1] & 0xffffc00000000000ull;
360 y.w[0] = 0x0ull;
361 }
362 } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) { // y = inf
363 y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
364 y.w[0] = 0x0ull;
365 } else { // y is not special
366 // check for non-canonical values - treated as zero
367 if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // G0_G1=11
368 // non-canonical
369 y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
370 y.w[0] = 0x0ull;
371 } else { // G0_G1 != 11
372 if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
373 ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
374 && y.w[0] > 0x378d8e63ffffffffull)) {
375 // y is non-canonical if coefficient is larger than 10^34 -1
376 y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
377 y.w[0] = 0x0ull;
378 } else { // canonical
379 ;
380 }
381 }
382 }
383
384 // NaN (CASE1)
385 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
386 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNaN
387 // if x is SNAN, then return quiet (x)
388 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
389 x.w[1] = x.w[1] & 0xfdffffffffffffffull; // quietize x
390 res = x;
391 } else { // x is QNaN
392 if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
393 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
394 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
395 }
396 res = x;
397 } else {
398 res = y;
399 }
200359e8 400 }
200359e8 401 BID_RETURN (res);
b2a00c89
L
402 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
403 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
404 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
405 y.w[1] = y.w[1] & 0xfdffffffffffffffull; // quietize y
406 res = y;
407 } else {
408 // will return x (which is not NaN)
409 res = x;
200359e8 410 }
200359e8
L
411 BID_RETURN (res);
412 }
413 // SIMPLE (CASE2)
414 // if all the bits are the same, these numbers are equal (not Greater).
415 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
416 res = y;
417 BID_RETURN (res);
418 }
419 // INFINITY (CASE3)
420 if ((x.w[1] & MASK_INF) == MASK_INF) {
421 // if x infinity, it has maximum magnitude.
422 // Check if magnitudes are equal. If x is negative, return it.
423 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN
b2a00c89 424 && (y.w[1] & MASK_INF) == MASK_INF) ? x : y;
200359e8
L
425 BID_RETURN (res);
426 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
427 // x is finite, so if y is infinity, then x is less in magnitude
428 res = x;
429 BID_RETURN (res);
430 }
431 // CONVERT X
432 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
433 sig_x.w[0] = x.w[0];
434 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
435
200359e8
L
436 // CONVERT Y
437 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
438 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
439 sig_y.w[0] = y.w[0];
440
200359e8
L
441 // ZERO (CASE4)
442 // some properties:
443 // (+ZERO == -ZERO) => therefore ignore the sign
444 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
445 // therefore ignore the exponent field
446 // (Any non-canonical # is considered 0)
b2a00c89 447 if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
200359e8
L
448 res = x;
449 BID_RETURN (res);
450 }
b2a00c89 451 if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
200359e8
L
452 res = y;
453 BID_RETURN (res);
454 }
455 // REDUNDANT REPRESENTATIONS (CASE6)
456 // check if exponents are the same and significands are the same
457 if (exp_y == exp_x && sig_x.w[1] == sig_y.w[1]
458 && sig_x.w[0] == sig_y.w[0]) {
b2a00c89 459 if (x.w[1] & 0x8000000000000000ull) { // x is negative
200359e8
L
460 res = x;
461 BID_RETURN (res);
462 } else {
463 res = y;
464 BID_RETURN (res);
465 }
466 } else if (((sig_x.w[1] > sig_y.w[1] || (sig_x.w[1] == sig_y.w[1]
b2a00c89
L
467 && sig_x.w[0] > sig_y.w[0]))
468 && exp_x == exp_y)
469 || ((sig_x.w[1] > sig_y.w[1]
470 || (sig_x.w[1] == sig_y.w[1]
471 && sig_x.w[0] >= sig_y.w[0]))
472 && exp_x > exp_y)) {
200359e8
L
473 // if both components are either bigger or smaller, it is clear what
474 // needs to be done; also if the magnitudes are equal
475 res = y;
476 BID_RETURN (res);
477 } else if (((sig_y.w[1] > sig_x.w[1] || (sig_y.w[1] == sig_x.w[1]
b2a00c89
L
478 && sig_y.w[0] > sig_x.w[0]))
479 && exp_y == exp_x)
480 || ((sig_y.w[1] > sig_x.w[1]
481 || (sig_y.w[1] == sig_x.w[1]
482 && sig_y.w[0] >= sig_x.w[0]))
483 && exp_y > exp_x)) {
200359e8
L
484 res = x;
485 BID_RETURN (res);
486 } else {
b2a00c89 487 ; // continue
200359e8
L
488 }
489 diff = exp_x - exp_y;
490 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
b2a00c89 491 if (diff > 0) { // to simplify the loop below,
200359e8
L
492 // if exp_x is 33 greater than exp_y, no need for compensation
493 if (diff > 33) {
b2a00c89 494 res = y; // difference cannot be greater than 10^33
200359e8
L
495 BID_RETURN (res);
496 }
b2a00c89
L
497 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
498 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
200359e8
L
499 // if positive, return whichever significand is larger
500 // (converse if negative)
501 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
b2a00c89
L
502 && sig_n_prime256.w[1] == sig_y.w[1]
503 && (sig_n_prime256.w[0] == sig_y.w[0])) {
504 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x; // if equal
505 BID_RETURN (res);
200359e8
L
506 }
507 res = (((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
b2a00c89
L
508 || (sig_n_prime256.w[1] > sig_y.w[1])
509 || (sig_n_prime256.w[1] == sig_y.w[1]
510 && sig_n_prime256.w[0] > sig_y.w[0])) ? y : x;
200359e8
L
511 BID_RETURN (res);
512 }
b2a00c89 513 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
200359e8
L
514 // if positive, return whichever significand is larger
515 // (converse if negative)
516 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
b2a00c89 517 && (sig_n_prime192.w[0] == sig_y.w[0])) {
200359e8
L
518 // if = in magnitude, return +, (if possible)
519 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
520 BID_RETURN (res);
521 }
522 res = ((sig_n_prime192.w[2] > 0)
b2a00c89
L
523 || (sig_n_prime192.w[1] > sig_y.w[1])
524 || (sig_n_prime192.w[1] == sig_y.w[1]
525 && sig_n_prime192.w[0] > sig_y.w[0])) ? y : x;
200359e8
L
526 BID_RETURN (res);
527 }
528 diff = exp_y - exp_x;
529 // if exp_x is 33 less than exp_y, no need for compensation
530 if (diff > 33) {
531 res = x;
532 BID_RETURN (res);
533 }
b2a00c89 534 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
200359e8 535 // adjust the y significand upwards
b2a00c89 536 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
200359e8
L
537 // if positive, return whichever significand is larger
538 // (converse if negative)
539 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
b2a00c89
L
540 && sig_n_prime256.w[1] == sig_x.w[1]
541 && (sig_n_prime256.w[0] == sig_x.w[0])) {
200359e8
L
542 // if = in magnitude, return +, (if possible)
543 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
544 BID_RETURN (res);
545 }
546 res = (sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
b2a00c89
L
547 && (sig_n_prime256.w[1] < sig_x.w[1]
548 || (sig_n_prime256.w[1] == sig_x.w[1]
549 && sig_n_prime256.w[0] < sig_x.w[0]))) ? y : x;
200359e8
L
550 BID_RETURN (res);
551 }
552 // adjust the y significand upwards
b2a00c89 553 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
200359e8
L
554 // if positive, return whichever significand is larger (converse if negative)
555 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
556 && (sig_n_prime192.w[0] == sig_x.w[0])) {
557 // if = in magnitude, return +, if possible)
558 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
559 BID_RETURN (res);
560 }
b2a00c89
L
561 res = (sig_n_prime192.w[2] == 0
562 && (sig_n_prime192.w[1] < sig_x.w[1]
563 || (sig_n_prime192.w[1] == sig_x.w[1]
564 && sig_n_prime192.w[0] < sig_x.w[0]))) ? y : x;
200359e8
L
565 BID_RETURN (res);
566}
567
568/*****************************************************************************
569 * BID128 maximum function - returns greater of two numbers
570 *****************************************************************************/
571
572#if DECIMAL_CALL_BY_REFERENCE
573void
b2a00c89
L
574bid128_maxnum (UINT128 * pres, UINT128 * px,
575 UINT128 * py _EXC_FLAGS_PARAM) {
200359e8
L
576 UINT128 x = *px;
577 UINT128 y = *py;
578#else
579UINT128
b2a00c89 580bid128_maxnum (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
200359e8
L
581#endif
582
583 UINT128 res;
584 int exp_x, exp_y;
585 int diff;
586 UINT128 sig_x, sig_y;
587 UINT192 sig_n_prime192;
588 UINT256 sig_n_prime256;
b2a00c89 589 char x_is_zero = 0, y_is_zero = 0;
200359e8 590
b2a00c89
L
591 BID_SWAP128 (x);
592 BID_SWAP128 (y);
593
594 // check for non-canonical x
595 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
596 x.w[1] = x.w[1] & 0xfe003fffffffffffull; // clear out G[6]-G[16]
597 // check for non-canonical NaN payload
598 if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
599 (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
600 (x.w[0] > 0x38c15b09ffffffffull))) {
601 x.w[1] = x.w[1] & 0xffffc00000000000ull;
602 x.w[0] = 0x0ull;
200359e8 603 }
b2a00c89
L
604 } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) { // x = inf
605 x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
606 x.w[0] = 0x0ull;
607 } else { // x is not special
608 // check for non-canonical values - treated as zero
609 if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // G0_G1=11
610 // non-canonical
611 x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
612 x.w[0] = 0x0ull;
613 } else { // G0_G1 != 11
614 if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
615 ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
616 && x.w[0] > 0x378d8e63ffffffffull)) {
617 // x is non-canonical if coefficient is larger than 10^34 -1
618 x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
619 x.w[0] = 0x0ull;
620 } else { // canonical
621 ;
622 }
623 }
624 }
625 // check for non-canonical y
626 if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
627 y.w[1] = y.w[1] & 0xfe003fffffffffffull; // clear out G[6]-G[16]
628 // check for non-canonical NaN payload
629 if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
630 (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
631 (y.w[0] > 0x38c15b09ffffffffull))) {
632 y.w[1] = y.w[1] & 0xffffc00000000000ull;
633 y.w[0] = 0x0ull;
634 }
635 } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) { // y = inf
636 y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
637 y.w[0] = 0x0ull;
638 } else { // y is not special
639 // check for non-canonical values - treated as zero
640 if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // G0_G1=11
641 // non-canonical
642 y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
643 y.w[0] = 0x0ull;
644 } else { // G0_G1 != 11
645 if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
646 ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
647 && y.w[0] > 0x378d8e63ffffffffull)) {
648 // y is non-canonical if coefficient is larger than 10^34 -1
649 y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
650 y.w[0] = 0x0ull;
651 } else { // canonical
652 ;
653 }
654 }
655 }
656
657 // NaN (CASE1)
658 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
659 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNaN
660 // if x is SNAN, then return quiet (x)
661 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
662 x.w[1] = x.w[1] & 0xfdffffffffffffffull; // quietize x
663 res = x;
664 } else { // x is QNaN
665 if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
666 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
667 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
668 }
669 res = x;
670 } else {
671 res = y;
672 }
200359e8 673 }
200359e8 674 BID_RETURN (res);
b2a00c89
L
675 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
676 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
677 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
678 y.w[1] = y.w[1] & 0xfdffffffffffffffull; // quietize y
679 res = y;
680 } else {
681 // will return x (which is not NaN)
682 res = x;
200359e8 683 }
200359e8
L
684 BID_RETURN (res);
685 }
686 // SIMPLE (CASE2)
687 // if all the bits are the same, these numbers are equal (not Greater).
688 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
689 res = x;
690 BID_RETURN (res);
691 }
692 // INFINITY (CASE3)
693 if ((x.w[1] & MASK_INF) == MASK_INF) {
694 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? y : x;
695 BID_RETURN (res);
696 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
697 // x is finite, so if y is positive infinity, then x is less, return 0
698 // if y is negative infinity, then x is greater, return 1
699 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
700 BID_RETURN (res);
701 }
702 // CONVERT X
703 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
704 sig_x.w[0] = x.w[0];
705 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
706
200359e8
L
707 // CONVERT Y
708 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
709 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
710 sig_y.w[0] = y.w[0];
711
200359e8
L
712 // ZERO (CASE4)
713 // some properties:
714 // (+ZERO == -ZERO) => therefore ignore the sign
715 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
716 // therefore ignore the exponent field
717 // (Any non-canonical # is considered 0)
b2a00c89 718 if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
200359e8
L
719 x_is_zero = 1;
720 }
b2a00c89 721 if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
200359e8
L
722 y_is_zero = 1;
723 }
724
725 if (x_is_zero && y_is_zero) {
726 // if both numbers are zero, neither is greater => return either number
727 res = x;
728 BID_RETURN (res);
729 } else if (x_is_zero) {
730 // is x is zero, it is greater if Y is negative
731 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
732 BID_RETURN (res);
733 } else if (y_is_zero) {
734 // is y is zero, X is greater if it is positive
735 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
736 BID_RETURN (res);
737 }
738 // OPPOSITE SIGN (CASE5)
739 // now, if the sign bits differ, x is greater if y is negative
740 if (((x.w[1] ^ y.w[1]) & MASK_SIGN) == MASK_SIGN) {
741 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
742 BID_RETURN (res);
743 }
744 // REDUNDANT REPRESENTATIONS (CASE6)
745 // if exponents are the same, then we have a simple comparison of
746 // the significands
747 if (exp_y == exp_x) {
b2a00c89
L
748 res = (((sig_x.w[1] > sig_y.w[1]) || (sig_x.w[1] == sig_y.w[1] &&
749 sig_x.w[0] >= sig_y.w[0])) ^
750 ((x.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
200359e8
L
751 BID_RETURN (res);
752 }
753 // if both components are either bigger or smaller, it is clear what
754 // needs to be done
755 if ((sig_x.w[1] > sig_y.w[1]
756 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0]))
757 && exp_x >= exp_y) {
758 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
759 BID_RETURN (res);
760 }
761 if ((sig_x.w[1] < sig_y.w[1]
762 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0]))
763 && exp_x <= exp_y) {
764 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
765 BID_RETURN (res);
766 }
767 diff = exp_x - exp_y;
768 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
b2a00c89 769 if (diff > 0) { // to simplify the loop below,
200359e8
L
770 // if exp_x is 33 greater than exp_y, no need for compensation
771 if (diff > 33) {
772 // difference cannot be greater than 10^33
773 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN) ? x : y;
774 BID_RETURN (res);
775 }
b2a00c89
L
776 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
777 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
200359e8
L
778 // if postitive, return whichever significand is larger
779 // (converse if negative)
780 res = ((((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
b2a00c89
L
781 || (sig_n_prime256.w[1] > sig_y.w[1])
782 || (sig_n_prime256.w[1] == sig_y.w[1]
783 && sig_n_prime256.w[0] >
784 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) ==
785 MASK_SIGN)) ? x : y;
200359e8
L
786 BID_RETURN (res);
787 }
b2a00c89 788 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
200359e8
L
789 // if postitive, return whichever significand is larger
790 // (converse if negative)
791 res =
792 (((sig_n_prime192.w[2] > 0) || (sig_n_prime192.w[1] > sig_y.w[1])
b2a00c89
L
793 || (sig_n_prime192.w[1] == sig_y.w[1]
794 && sig_n_prime192.w[0] >
795 sig_y.w[0])) ^ ((y.w[1] & MASK_SIGN) == MASK_SIGN)) ? x : y;
200359e8
L
796 BID_RETURN (res);
797 }
798 diff = exp_y - exp_x;
799 // if exp_x is 33 less than exp_y, no need for compensation
800 if (diff > 33) {
801 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
802 BID_RETURN (res);
803 }
b2a00c89 804 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
200359e8 805 // adjust the y significand upwards
b2a00c89 806 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
200359e8
L
807 // if postitive, return whichever significand is larger
808 // (converse if negative)
809 res =
810 ((sig_n_prime256.w[3] != 0 || sig_n_prime256.w[2] != 0
b2a00c89
L
811 || (sig_n_prime256.w[1] > sig_x.w[1]
812 || (sig_n_prime256.w[1] == sig_x.w[1]
813 && sig_n_prime256.w[0] >
814 sig_x.w[0]))) ^ ((x.w[1] & MASK_SIGN) !=
815 MASK_SIGN)) ? x : y;
200359e8
L
816 BID_RETURN (res);
817 }
818 // adjust the y significand upwards
b2a00c89 819 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
200359e8 820 // if postitive, return whichever significand is larger (converse if negative)
b2a00c89
L
821 res =
822 ((sig_n_prime192.w[2] != 0
823 || (sig_n_prime192.w[1] > sig_x.w[1]
824 || (sig_n_prime192.w[1] == sig_x.w[1]
825 && sig_n_prime192.w[0] >
826 sig_x.w[0]))) ^ ((y.w[1] & MASK_SIGN) !=
827 MASK_SIGN)) ? x : y;
200359e8
L
828 BID_RETURN (res);
829}
830
831/*****************************************************************************
832 * BID128 maximum magnitude function - returns greater of two numbers
833 *****************************************************************************/
834
835#if DECIMAL_CALL_BY_REFERENCE
836void
b2a00c89
L
837bid128_maxnum_mag (UINT128 * pres, UINT128 * px,
838 UINT128 * py _EXC_FLAGS_PARAM) {
200359e8
L
839 UINT128 x = *px;
840 UINT128 y = *py;
841#else
842UINT128
b2a00c89 843bid128_maxnum_mag (UINT128 x, UINT128 y _EXC_FLAGS_PARAM) {
200359e8
L
844#endif
845
846 UINT128 res;
847 int exp_x, exp_y;
848 int diff;
849 UINT128 sig_x, sig_y;
850 UINT192 sig_n_prime192;
851 UINT256 sig_n_prime256;
200359e8 852
b2a00c89
L
853 BID_SWAP128 (x);
854 BID_SWAP128 (y);
855
856 // check for non-canonical x
857 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
858 x.w[1] = x.w[1] & 0xfe003fffffffffffull; // clear out G[6]-G[16]
859 // check for non-canonical NaN payload
860 if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
861 (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
862 (x.w[0] > 0x38c15b09ffffffffull))) {
863 x.w[1] = x.w[1] & 0xffffc00000000000ull;
864 x.w[0] = 0x0ull;
200359e8 865 }
b2a00c89
L
866 } else if ((x.w[1] & MASK_ANY_INF) == MASK_INF) { // x = inf
867 x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
868 x.w[0] = 0x0ull;
869 } else { // x is not special
870 // check for non-canonical values - treated as zero
871 if ((x.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // G0_G1=11
872 // non-canonical
873 x.w[1] = (x.w[1] & MASK_SIGN) | ((x.w[1] << 2) & MASK_EXP);
874 x.w[0] = 0x0ull;
875 } else { // G0_G1 != 11
876 if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
877 ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
878 && x.w[0] > 0x378d8e63ffffffffull)) {
879 // x is non-canonical if coefficient is larger than 10^34 -1
880 x.w[1] = (x.w[1] & MASK_SIGN) | (x.w[1] & MASK_EXP);
881 x.w[0] = 0x0ull;
882 } else { // canonical
883 ;
884 }
885 }
886 }
887 // check for non-canonical y
888 if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
889 y.w[1] = y.w[1] & 0xfe003fffffffffffull; // clear out G[6]-G[16]
890 // check for non-canonical NaN payload
891 if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
892 (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
893 (y.w[0] > 0x38c15b09ffffffffull))) {
894 y.w[1] = y.w[1] & 0xffffc00000000000ull;
895 y.w[0] = 0x0ull;
896 }
897 } else if ((y.w[1] & MASK_ANY_INF) == MASK_INF) { // y = inf
898 y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
899 y.w[0] = 0x0ull;
900 } else { // y is not special
901 // check for non-canonical values - treated as zero
902 if ((y.w[1] & MASK_STEERING_BITS) == MASK_STEERING_BITS) { // G0_G1=11
903 // non-canonical
904 y.w[1] = (y.w[1] & MASK_SIGN) | ((y.w[1] << 2) & MASK_EXP);
905 y.w[0] = 0x0ull;
906 } else { // G0_G1 != 11
907 if ((y.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
908 ((y.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull &&
909 y.w[0] > 0x378d8e63ffffffffull)) {
910 // y is non-canonical if coefficient is larger than 10^34 -1
911 y.w[1] = (y.w[1] & MASK_SIGN) | (y.w[1] & MASK_EXP);
912 y.w[0] = 0x0ull;
913 } else { // canonical
914 ;
915 }
916 }
917 }
918
919 // NaN (CASE1)
920 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
921 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNaN
922 // if x is SNAN, then return quiet (x)
923 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
924 x.w[1] = x.w[1] & 0xfdffffffffffffffull; // quietize x
925 res = x;
926 } else { // x is QNaN
927 if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
928 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
929 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
930 }
931 res = x;
932 } else {
933 res = y;
934 }
200359e8 935 }
200359e8 936 BID_RETURN (res);
b2a00c89
L
937 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
938 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
939 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
940 y.w[1] = y.w[1] & 0xfdffffffffffffffull; // quietize y
941 res = y;
942 } else {
943 // will return x (which is not NaN)
944 res = x;
200359e8 945 }
200359e8
L
946 BID_RETURN (res);
947 }
948 // SIMPLE (CASE2)
949 // if all the bits are the same, these numbers are equal (not Greater).
950 if (x.w[0] == y.w[0] && x.w[1] == y.w[1]) {
951 res = y;
952 BID_RETURN (res);
953 }
954 // INFINITY (CASE3)
955 if ((x.w[1] & MASK_INF) == MASK_INF) {
956 // if x infinity, it has maximum magnitude
957 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN
b2a00c89 958 && (y.w[1] & MASK_INF) == MASK_INF) ? y : x;
200359e8
L
959 BID_RETURN (res);
960 } else if ((y.w[1] & MASK_INF) == MASK_INF) {
961 // x is finite, so if y is positive infinity, then x is less, return 0
962 // if y is negative infinity, then x is greater, return 1
963 res = y;
964 BID_RETURN (res);
965 }
966 // CONVERT X
967 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull;
968 sig_x.w[0] = x.w[0];
969 exp_x = (x.w[1] >> 49) & 0x000000000003fffull;
970
200359e8
L
971 // CONVERT Y
972 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull;
973 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull;
974 sig_y.w[0] = y.w[0];
975
200359e8
L
976 // ZERO (CASE4)
977 // some properties:
978 // (+ZERO == -ZERO) => therefore ignore the sign
979 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
980 // therefore ignore the exponent field
981 // (Any non-canonical # is considered 0)
b2a00c89 982 if ((sig_x.w[1] == 0) && (sig_x.w[0] == 0)) {
200359e8
L
983 res = y;
984 BID_RETURN (res);
985 }
b2a00c89 986 if ((sig_y.w[1] == 0) && (sig_y.w[0] == 0)) {
200359e8
L
987 res = x;
988 BID_RETURN (res);
989 }
990 // REDUNDANT REPRESENTATIONS (CASE6)
991 if (exp_y == exp_x && sig_x.w[1] == sig_y.w[1]
992 && sig_x.w[0] == sig_y.w[0]) {
993 // check if exponents are the same and significands are the same
b2a00c89 994 if (x.w[1] & 0x8000000000000000ull) { // x is negative
200359e8
L
995 res = y;
996 BID_RETURN (res);
997 } else {
998 res = x;
999 BID_RETURN (res);
1000 }
1001 } else if (((sig_x.w[1] > sig_y.w[1] || (sig_x.w[1] == sig_y.w[1]
b2a00c89
L
1002 && sig_x.w[0] > sig_y.w[0]))
1003 && exp_x == exp_y)
1004 || ((sig_x.w[1] > sig_y.w[1]
1005 || (sig_x.w[1] == sig_y.w[1]
1006 && sig_x.w[0] >= sig_y.w[0]))
1007 && exp_x > exp_y)) {
200359e8
L
1008 // if both components are either bigger or smaller, it is clear what
1009 // needs to be done; also if the magnitudes are equal
1010 res = x;
1011 BID_RETURN (res);
1012 } else if (((sig_y.w[1] > sig_x.w[1] || (sig_y.w[1] == sig_x.w[1]
b2a00c89
L
1013 && sig_y.w[0] > sig_x.w[0]))
1014 && exp_y == exp_x)
1015 || ((sig_y.w[1] > sig_x.w[1]
1016 || (sig_y.w[1] == sig_x.w[1]
1017 && sig_y.w[0] >= sig_x.w[0]))
1018 && exp_y > exp_x)) {
200359e8
L
1019 res = y;
1020 BID_RETURN (res);
1021 } else {
b2a00c89 1022 ; // continue
200359e8
L
1023 }
1024 diff = exp_x - exp_y;
1025 // if |exp_x - exp_y| < 33, it comes down to the compensated significand
b2a00c89 1026 if (diff > 0) { // to simplify the loop below,
200359e8
L
1027 // if exp_x is 33 greater than exp_y, no need for compensation
1028 if (diff > 33) {
b2a00c89 1029 res = x; // difference cannot be greater than 10^33
200359e8
L
1030 BID_RETURN (res);
1031 }
b2a00c89
L
1032 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
1033 __mul_128x128_to_256 (sig_n_prime256, sig_x, ten2k128[diff - 20]);
200359e8
L
1034 // if postitive, return whichever significand is larger
1035 // (converse if negative)
1036 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
b2a00c89
L
1037 && sig_n_prime256.w[1] == sig_y.w[1]
1038 && (sig_n_prime256.w[0] == sig_y.w[0])) {
1039 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y; // if equal
1040 BID_RETURN (res);
200359e8
L
1041 }
1042 res = (((sig_n_prime256.w[3] > 0) || sig_n_prime256.w[2] > 0)
b2a00c89
L
1043 || (sig_n_prime256.w[1] > sig_y.w[1])
1044 || (sig_n_prime256.w[1] == sig_y.w[1]
1045 && sig_n_prime256.w[0] > sig_y.w[0])) ? x : y;
200359e8
L
1046 BID_RETURN (res);
1047 }
b2a00c89 1048 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_x);
200359e8
L
1049 // if postitive, return whichever significand is larger (converse if negative)
1050 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1]
b2a00c89 1051 && (sig_n_prime192.w[0] == sig_y.w[0])) {
200359e8
L
1052 // if equal, return positive magnitude
1053 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
1054 BID_RETURN (res);
1055 }
1056 res = ((sig_n_prime192.w[2] > 0)
b2a00c89
L
1057 || (sig_n_prime192.w[1] > sig_y.w[1])
1058 || (sig_n_prime192.w[1] == sig_y.w[1]
1059 && sig_n_prime192.w[0] > sig_y.w[0])) ? x : y;
200359e8
L
1060 BID_RETURN (res);
1061 }
1062 diff = exp_y - exp_x;
1063 // if exp_x is 33 less than exp_y, no need for compensation
1064 if (diff > 33) {
1065 res = y;
1066 BID_RETURN (res);
1067 }
b2a00c89 1068 if (diff > 19) { //128 by 128 bit multiply -> 256 bits
200359e8 1069 // adjust the y significand upwards
b2a00c89 1070 __mul_128x128_to_256 (sig_n_prime256, sig_y, ten2k128[diff - 20]);
200359e8
L
1071 // if postitive, return whichever significand is larger
1072 // (converse if negative)
1073 if (sig_n_prime256.w[3] == 0 && (sig_n_prime256.w[2] == 0)
b2a00c89
L
1074 && sig_n_prime256.w[1] == sig_x.w[1]
1075 && (sig_n_prime256.w[0] == sig_x.w[0])) {
200359e8
L
1076 // if equal, return positive (if possible)
1077 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
1078 BID_RETURN (res);
1079 }
1080 res = (sig_n_prime256.w[3] == 0 && sig_n_prime256.w[2] == 0
b2a00c89
L
1081 && (sig_n_prime256.w[1] < sig_x.w[1]
1082 || (sig_n_prime256.w[1] == sig_x.w[1]
1083 && sig_n_prime256.w[0] < sig_x.w[0]))) ? x : y;
200359e8
L
1084 BID_RETURN (res);
1085 }
1086 // adjust the y significand upwards
b2a00c89 1087 __mul_64x128_to_192 (sig_n_prime192, ten2k64[diff], sig_y);
200359e8
L
1088 // if postitive, return whichever significand is larger (converse if negative)
1089 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_x.w[1]
1090 && (sig_n_prime192.w[0] == sig_x.w[0])) {
1091 // if equal, return positive (if possible)
1092 res = ((y.w[1] & MASK_SIGN) == MASK_SIGN) ? x : y;
1093 BID_RETURN (res);
1094 }
b2a00c89
L
1095 res = (sig_n_prime192.w[2] == 0
1096 && (sig_n_prime192.w[1] < sig_x.w[1]
1097 || (sig_n_prime192.w[1] == sig_x.w[1]
1098 && sig_n_prime192.w[0] < sig_x.w[0]))) ? x : y;
200359e8
L
1099 BID_RETURN (res);
1100}