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