]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/libbid/bid64_minmax.c
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / libbid / bid64_minmax.c
CommitLineData
85ec4feb 1/* Copyright (C) 2007-2018 Free Software Foundation, Inc.
200359e8
L
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
748086b7 7Software Foundation; either version 3, or (at your option) any later
200359e8
L
8version.
9
200359e8
L
10GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11WARRANTY; without even the implied warranty of MERCHANTABILITY or
12FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13for more details.
14
748086b7
JJ
15Under Section 7 of GPL version 3, you are granted additional
16permissions described in the GCC Runtime Library Exception, version
173.1, as published by the Free Software Foundation.
18
19You should have received a copy of the GNU General Public License and
20a copy of the GCC Runtime Library Exception along with this program;
21see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22<http://www.gnu.org/licenses/>. */
200359e8
L
23
24#include "bid_internal.h"
25
26/*****************************************************************************
27 * BID64 minimum function - returns greater of two numbers
28 *****************************************************************************/
29
30static const UINT64 mult_factor[16] = {
31 1ull, 10ull, 100ull, 1000ull,
32 10000ull, 100000ull, 1000000ull, 10000000ull,
33 100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
34 1000000000000ull, 10000000000000ull,
35 100000000000000ull, 1000000000000000ull
36};
37
38#if DECIMAL_CALL_BY_REFERENCE
39void
b2a00c89 40bid64_minnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
200359e8
L
41 UINT64 x = *px;
42 UINT64 y = *py;
43#else
44UINT64
b2a00c89 45bid64_minnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
200359e8
L
46#endif
47
48 UINT64 res;
49 int exp_x, exp_y;
50 UINT64 sig_x, sig_y;
51 UINT128 sig_n_prime;
b2a00c89 52 char x_is_zero = 0, y_is_zero = 0;
200359e8 53
b2a00c89
L
54 // check for non-canonical x
55 if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
56 x = x & 0xfe03ffffffffffffull; // clear G6-G12
57 if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
58 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
200359e8 59 }
b2a00c89
L
60 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
61 x = x & (MASK_SIGN | MASK_INF);
62 } else { // x is not special
63 // check for non-canonical values - treated as zero
64 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
65 // if the steering bits are 11, then the exponent is G[0:w+1]
66 if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
67 9999999999999999ull) {
68 // non-canonical
69 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
70 } // else canonical
71 } // else canonical
72 }
73
74 // check for non-canonical y
75 if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
76 y = y & 0xfe03ffffffffffffull; // clear G6-G12
77 if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
78 y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
200359e8 79 }
b2a00c89
L
80 } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
81 y = y & (MASK_SIGN | MASK_INF);
82 } else { // y is not special
83 // check for non-canonical values - treated as zero
84 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
85 // if the steering bits are 11, then the exponent is G[0:w+1]
86 if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
87 9999999999999999ull) {
88 // non-canonical
89 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
90 } // else canonical
91 } // else canonical
200359e8 92 }
b2a00c89
L
93
94 // NaN (CASE1)
95 if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
96 if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
97 // if x is SNAN, then return quiet (x)
98 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
99 x = x & 0xfdffffffffffffffull; // quietize x
100 res = x;
101 } else { // x is QNaN
102 if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
103 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
104 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
105 }
106 res = x;
107 } else {
108 res = y;
109 }
110 }
111 BID_RETURN (res);
112 } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
113 if ((y & MASK_SNAN) == MASK_SNAN) {
114 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
115 y = y & 0xfdffffffffffffffull; // quietize y
116 res = y;
117 } else {
118 // will return x (which is not NaN)
119 res = x;
200359e8 120 }
200359e8
L
121 BID_RETURN (res);
122 }
123 // SIMPLE (CASE2)
124 // if all the bits are the same, these numbers are equal, return either number
125 if (x == y) {
126 res = x;
127 BID_RETURN (res);
128 }
129 // INFINITY (CASE3)
130 if ((x & MASK_INF) == MASK_INF) {
131 // if x is neg infinity, there is no way it is greater than y, return x
132 if (((x & MASK_SIGN) == MASK_SIGN)) {
133 res = x;
134 BID_RETURN (res);
135 }
136 // x is pos infinity, return y
137 else {
138 res = y;
139 BID_RETURN (res);
140 }
141 } else if ((y & MASK_INF) == MASK_INF) {
142 // x is finite, so if y is positive infinity, then x is less, return y
143 // if y is negative infinity, then x is greater, return x
144 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
145 BID_RETURN (res);
146 }
147 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
148 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
149 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
150 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
200359e8
L
151 } else {
152 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
153 sig_x = (x & MASK_BINARY_SIG1);
200359e8
L
154 }
155
156 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
157 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
158 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
159 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
200359e8
L
160 } else {
161 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
162 sig_y = (y & MASK_BINARY_SIG1);
200359e8
L
163 }
164
165 // ZERO (CASE4)
166 // some properties:
167 // (+ZERO == -ZERO) => therefore
168 // ignore the sign, and neither number is greater
169 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
170 // ignore the exponent field
171 // (Any non-canonical # is considered 0)
b2a00c89 172 if (sig_x == 0) {
200359e8
L
173 x_is_zero = 1;
174 }
b2a00c89 175 if (sig_y == 0) {
200359e8
L
176 y_is_zero = 1;
177 }
178
179 if (x_is_zero && y_is_zero) {
180 // if both numbers are zero, neither is greater => return either
181 res = y;
182 BID_RETURN (res);
183 } else if (x_is_zero) {
184 // is x is zero, it is greater if Y is negative
185 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
186 BID_RETURN (res);
187 } else if (y_is_zero) {
188 // is y is zero, X is greater if it is positive
189 res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x;;
190 BID_RETURN (res);
191 }
192 // OPPOSITE SIGN (CASE5)
193 // now, if the sign bits differ, x is greater if y is negative
194 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) {
195 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
196 BID_RETURN (res);
197 }
198 // REDUNDANT REPRESENTATIONS (CASE6)
199
200 // if both components are either bigger or smaller,
201 // it is clear what needs to be done
202 if (sig_x > sig_y && exp_x >= exp_y) {
203 res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x;
204 BID_RETURN (res);
205 }
206 if (sig_x < sig_y && exp_x <= exp_y) {
207 res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
208 BID_RETURN (res);
209 }
210 // if exp_x is 15 greater than exp_y, no need for compensation
211 if (exp_x - exp_y > 15) {
b2a00c89 212 res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x; // difference cannot be >10^15
200359e8
L
213 BID_RETURN (res);
214 }
215 // if exp_x is 15 less than exp_y, no need for compensation
216 if (exp_y - exp_x > 15) {
217 res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
218 BID_RETURN (res);
219 }
220 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
b2a00c89 221 if (exp_x > exp_y) { // to simplify the loop below,
200359e8
L
222
223 // otherwise adjust the x significand upwards
224 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
225 mult_factor[exp_x - exp_y]);
226 // if postitive, return whichever significand is larger
227 // (converse if negative)
228 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
229 res = y;
230 BID_RETURN (res);
231 }
232
233 res = (((sig_n_prime.w[1] > 0)
234 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
235 MASK_SIGN)) ? y : x;
236 BID_RETURN (res);
237 }
238 // adjust the y significand upwards
239 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
240 mult_factor[exp_y - exp_x]);
241
242 // if postitive, return whichever significand is larger (converse if negative)
243 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
244 res = y;
245 BID_RETURN (res);
246 }
247 res = (((sig_n_prime.w[1] == 0)
248 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
249 MASK_SIGN)) ? y : x;
250 BID_RETURN (res);
251}
252
253/*****************************************************************************
254 * BID64 minimum magnitude function - returns greater of two numbers
255 *****************************************************************************/
256
257#if DECIMAL_CALL_BY_REFERENCE
258void
b2a00c89
L
259bid64_minnum_mag (UINT64 * pres, UINT64 * px,
260 UINT64 * py _EXC_FLAGS_PARAM) {
200359e8
L
261 UINT64 x = *px;
262 UINT64 y = *py;
263#else
264UINT64
b2a00c89 265bid64_minnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
200359e8
L
266#endif
267
268 UINT64 res;
269 int exp_x, exp_y;
270 UINT64 sig_x, sig_y;
271 UINT128 sig_n_prime;
200359e8 272
b2a00c89
L
273 // check for non-canonical x
274 if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
275 x = x & 0xfe03ffffffffffffull; // clear G6-G12
276 if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
277 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
200359e8 278 }
b2a00c89
L
279 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
280 x = x & (MASK_SIGN | MASK_INF);
281 } else { // x is not special
282 // check for non-canonical values - treated as zero
283 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
284 // if the steering bits are 11, then the exponent is G[0:w+1]
285 if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
286 9999999999999999ull) {
287 // non-canonical
288 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
289 } // else canonical
290 } // else canonical
291 }
292
293 // check for non-canonical y
294 if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
295 y = y & 0xfe03ffffffffffffull; // clear G6-G12
296 if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
297 y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
298 }
299 } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
300 y = y & (MASK_SIGN | MASK_INF);
301 } else { // y is not special
302 // check for non-canonical values - treated as zero
303 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
304 // if the steering bits are 11, then the exponent is G[0:w+1]
305 if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
306 9999999999999999ull) {
307 // non-canonical
308 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
309 } // else canonical
310 } // else canonical
311 }
312
313 // NaN (CASE1)
314 if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
315 if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
316 // if x is SNAN, then return quiet (x)
317 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
318 x = x & 0xfdffffffffffffffull; // quietize x
319 res = x;
320 } else { // x is QNaN
321 if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
322 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
323 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
324 }
325 res = x;
326 } else {
327 res = y;
328 }
200359e8 329 }
200359e8 330 BID_RETURN (res);
b2a00c89
L
331 } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
332 if ((y & MASK_SNAN) == MASK_SNAN) {
333 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
334 y = y & 0xfdffffffffffffffull; // quietize y
335 res = y;
336 } else {
337 // will return x (which is not NaN)
338 res = x;
200359e8 339 }
200359e8
L
340 BID_RETURN (res);
341 }
342 // SIMPLE (CASE2)
343 // if all the bits are the same, these numbers are equal, return either number
344 if (x == y) {
345 res = x;
346 BID_RETURN (res);
347 }
348 // INFINITY (CASE3)
349 if ((x & MASK_INF) == MASK_INF) {
350 // x is infinity, its magnitude is greater than or equal to y
351 // return x only if y is infinity and x is negative
352 res = ((x & MASK_SIGN) == MASK_SIGN
353 && (y & MASK_INF) == MASK_INF) ? x : y;
354 BID_RETURN (res);
355 } else if ((y & MASK_INF) == MASK_INF) {
356 // y is infinity, then it must be greater in magnitude, return x
357 res = x;
358 BID_RETURN (res);
359 }
360 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
361 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
362 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
363 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
200359e8
L
364 } else {
365 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
366 sig_x = (x & MASK_BINARY_SIG1);
200359e8
L
367 }
368
369 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
370 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
371 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
372 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
200359e8
L
373 } else {
374 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
375 sig_y = (y & MASK_BINARY_SIG1);
200359e8
L
376 }
377
378 // ZERO (CASE4)
379 // some properties:
380 // (+ZERO == -ZERO) => therefore
381 // ignore the sign, and neither number is greater
382 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
383 // ignore the exponent field
384 // (Any non-canonical # is considered 0)
b2a00c89
L
385 if (sig_x == 0) {
386 res = x; // x_is_zero, its magnitude must be smaller than y
200359e8
L
387 BID_RETURN (res);
388 }
b2a00c89
L
389 if (sig_y == 0) {
390 res = y; // y_is_zero, its magnitude must be smaller than x
200359e8
L
391 BID_RETURN (res);
392 }
393 // REDUNDANT REPRESENTATIONS (CASE6)
394 // if both components are either bigger or smaller,
395 // it is clear what needs to be done
396 if (sig_x > sig_y && exp_x >= exp_y) {
397 res = y;
398 BID_RETURN (res);
399 }
400 if (sig_x < sig_y && exp_x <= exp_y) {
401 res = x;
402 BID_RETURN (res);
403 }
404 // if exp_x is 15 greater than exp_y, no need for compensation
405 if (exp_x - exp_y > 15) {
b2a00c89 406 res = y; // difference cannot be greater than 10^15
200359e8
L
407 BID_RETURN (res);
408 }
409 // if exp_x is 15 less than exp_y, no need for compensation
410 if (exp_y - exp_x > 15) {
411 res = x;
412 BID_RETURN (res);
413 }
414 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
b2a00c89 415 if (exp_x > exp_y) { // to simplify the loop below,
200359e8
L
416 // otherwise adjust the x significand upwards
417 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
418 mult_factor[exp_x - exp_y]);
419 // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y), this is
420 // the compensated signif.
421 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
422 // two numbers are equal, return minNum(x,y)
423 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
424 BID_RETURN (res);
425 }
426 // now, if compensated_x (sig_n_prime) is greater than y, return y,
427 // otherwise return x
428 res = ((sig_n_prime.w[1] != 0) || sig_n_prime.w[0] > sig_y) ? y : x;
429 BID_RETURN (res);
430 }
431 // exp_y must be greater than exp_x, thus adjust the y significand upwards
432 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
433 mult_factor[exp_y - exp_x]);
434
435 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
b2a00c89
L
436 res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
437 // two numbers are equal, return either
200359e8
L
438 BID_RETURN (res);
439 }
440
441 res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? y : x;
442 BID_RETURN (res);
443}
444
445/*****************************************************************************
446 * BID64 maximum function - returns greater of two numbers
447 *****************************************************************************/
448
449#if DECIMAL_CALL_BY_REFERENCE
450void
b2a00c89 451bid64_maxnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
200359e8
L
452 UINT64 x = *px;
453 UINT64 y = *py;
454#else
455UINT64
b2a00c89 456bid64_maxnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
200359e8
L
457#endif
458
459 UINT64 res;
460 int exp_x, exp_y;
461 UINT64 sig_x, sig_y;
462 UINT128 sig_n_prime;
b2a00c89 463 char x_is_zero = 0, y_is_zero = 0;
200359e8 464
b2a00c89
L
465 // check for non-canonical x
466 if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
467 x = x & 0xfe03ffffffffffffull; // clear G6-G12
468 if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
469 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
200359e8 470 }
b2a00c89
L
471 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
472 x = x & (MASK_SIGN | MASK_INF);
473 } else { // x is not special
474 // check for non-canonical values - treated as zero
475 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
476 // if the steering bits are 11, then the exponent is G[0:w+1]
477 if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
478 9999999999999999ull) {
479 // non-canonical
480 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
481 } // else canonical
482 } // else canonical
483 }
484
485 // check for non-canonical y
486 if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
487 y = y & 0xfe03ffffffffffffull; // clear G6-G12
488 if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
489 y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
490 }
491 } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
492 y = y & (MASK_SIGN | MASK_INF);
493 } else { // y is not special
494 // check for non-canonical values - treated as zero
495 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
496 // if the steering bits are 11, then the exponent is G[0:w+1]
497 if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
498 9999999999999999ull) {
499 // non-canonical
500 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
501 } // else canonical
502 } // else canonical
503 }
504
505 // NaN (CASE1)
506 if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
507 if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
508 // if x is SNAN, then return quiet (x)
509 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
510 x = x & 0xfdffffffffffffffull; // quietize x
511 res = x;
512 } else { // x is QNaN
513 if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
514 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
515 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
516 }
517 res = x;
518 } else {
519 res = y;
520 }
200359e8 521 }
200359e8 522 BID_RETURN (res);
b2a00c89
L
523 } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
524 if ((y & MASK_SNAN) == MASK_SNAN) {
525 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
526 y = y & 0xfdffffffffffffffull; // quietize y
527 res = y;
528 } else {
529 // will return x (which is not NaN)
530 res = x;
200359e8 531 }
200359e8
L
532 BID_RETURN (res);
533 }
534 // SIMPLE (CASE2)
535 // if all the bits are the same, these numbers are equal (not Greater).
536 if (x == y) {
537 res = x;
538 BID_RETURN (res);
539 }
540 // INFINITY (CASE3)
541 if ((x & MASK_INF) == MASK_INF) {
542 // if x is neg infinity, there is no way it is greater than y, return y
543 // x is pos infinity, it is greater, unless y is positive infinity =>
544 // return y!=pos_infinity
545 if (((x & MASK_SIGN) == MASK_SIGN)) {
546 res = y;
547 BID_RETURN (res);
548 } else {
549 res = (((y & MASK_INF) != MASK_INF)
550 || ((y & MASK_SIGN) == MASK_SIGN)) ? x : y;
551 BID_RETURN (res);
552 }
553 } else if ((y & MASK_INF) == MASK_INF) {
554 // x is finite, so if y is positive infinity, then x is less, return y
555 // if y is negative infinity, then x is greater, return x
556 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
557 BID_RETURN (res);
558 }
559 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
560 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
561 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
562 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
200359e8
L
563 } else {
564 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
565 sig_x = (x & MASK_BINARY_SIG1);
200359e8
L
566 }
567
568 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
569 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
570 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
571 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
200359e8
L
572 } else {
573 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
574 sig_y = (y & MASK_BINARY_SIG1);
200359e8
L
575 }
576
577 // ZERO (CASE4)
578 // some properties:
579 // (+ZERO == -ZERO) => therefore
580 // ignore the sign, and neither number is greater
581 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
582 // ignore the exponent field
583 // (Any non-canonical # is considered 0)
b2a00c89 584 if (sig_x == 0) {
200359e8
L
585 x_is_zero = 1;
586 }
b2a00c89 587 if (sig_y == 0) {
200359e8
L
588 y_is_zero = 1;
589 }
590
591 if (x_is_zero && y_is_zero) {
592 // if both numbers are zero, neither is greater => return NOTGREATERTHAN
593 res = y;
594 BID_RETURN (res);
595 } else if (x_is_zero) {
596 // is x is zero, it is greater if Y is negative
597 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
598 BID_RETURN (res);
599 } else if (y_is_zero) {
600 // is y is zero, X is greater if it is positive
601 res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;;
602 BID_RETURN (res);
603 }
604 // OPPOSITE SIGN (CASE5)
605 // now, if the sign bits differ, x is greater if y is negative
606 if (((x ^ y) & MASK_SIGN) == MASK_SIGN) {
607 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
608 BID_RETURN (res);
609 }
610 // REDUNDANT REPRESENTATIONS (CASE6)
611
612 // if both components are either bigger or smaller,
613 // it is clear what needs to be done
614 if (sig_x > sig_y && exp_x >= exp_y) {
615 res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;
616 BID_RETURN (res);
617 }
618 if (sig_x < sig_y && exp_x <= exp_y) {
619 res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
620 BID_RETURN (res);
621 }
622 // if exp_x is 15 greater than exp_y, no need for compensation
623 if (exp_x - exp_y > 15) {
b2a00c89
L
624 res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;
625 // difference cannot be > 10^15
200359e8
L
626 BID_RETURN (res);
627 }
628 // if exp_x is 15 less than exp_y, no need for compensation
629 if (exp_y - exp_x > 15) {
630 res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
631 BID_RETURN (res);
632 }
633 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
b2a00c89 634 if (exp_x > exp_y) { // to simplify the loop below,
200359e8
L
635 // otherwise adjust the x significand upwards
636 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
637 mult_factor[exp_x - exp_y]);
638 // if postitive, return whichever significand is larger
639 // (converse if negative)
640 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
641 res = y;
642 BID_RETURN (res);
643 }
644 res = (((sig_n_prime.w[1] > 0)
645 || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
646 MASK_SIGN)) ? x : y;
647 BID_RETURN (res);
648 }
649 // adjust the y significand upwards
650 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
651 mult_factor[exp_y - exp_x]);
652
653 // if postitive, return whichever significand is larger (converse if negative)
654 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
655 res = y;
656 BID_RETURN (res);
657 }
658 res = (((sig_n_prime.w[1] == 0)
659 && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
660 MASK_SIGN)) ? x : y;
661 BID_RETURN (res);
662}
663
664/*****************************************************************************
665 * BID64 maximum magnitude function - returns greater of two numbers
666 *****************************************************************************/
667
668#if DECIMAL_CALL_BY_REFERENCE
669void
b2a00c89
L
670bid64_maxnum_mag (UINT64 * pres, UINT64 * px,
671 UINT64 * py _EXC_FLAGS_PARAM) {
200359e8
L
672 UINT64 x = *px;
673 UINT64 y = *py;
674#else
675UINT64
b2a00c89 676bid64_maxnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
200359e8
L
677#endif
678
679 UINT64 res;
680 int exp_x, exp_y;
681 UINT64 sig_x, sig_y;
682 UINT128 sig_n_prime;
200359e8 683
b2a00c89
L
684 // check for non-canonical x
685 if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
686 x = x & 0xfe03ffffffffffffull; // clear G6-G12
687 if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
688 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
200359e8 689 }
b2a00c89
L
690 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
691 x = x & (MASK_SIGN | MASK_INF);
692 } else { // x is not special
693 // check for non-canonical values - treated as zero
694 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
695 // if the steering bits are 11, then the exponent is G[0:w+1]
696 if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
697 9999999999999999ull) {
698 // non-canonical
699 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
700 } // else canonical
701 } // else canonical
702 }
703
704 // check for non-canonical y
705 if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
706 y = y & 0xfe03ffffffffffffull; // clear G6-G12
707 if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
708 y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
709 }
710 } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
711 y = y & (MASK_SIGN | MASK_INF);
712 } else { // y is not special
713 // check for non-canonical values - treated as zero
714 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
715 // if the steering bits are 11, then the exponent is G[0:w+1]
716 if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
717 9999999999999999ull) {
718 // non-canonical
719 y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
720 } // else canonical
721 } // else canonical
722 }
723
724 // NaN (CASE1)
725 if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
726 if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
727 // if x is SNAN, then return quiet (x)
728 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
729 x = x & 0xfdffffffffffffffull; // quietize x
730 res = x;
731 } else { // x is QNaN
732 if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
733 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
734 *pfpsf |= INVALID_EXCEPTION; // set invalid flag
735 }
736 res = x;
737 } else {
738 res = y;
739 }
200359e8 740 }
200359e8 741 BID_RETURN (res);
b2a00c89
L
742 } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
743 if ((y & MASK_SNAN) == MASK_SNAN) {
744 *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
745 y = y & 0xfdffffffffffffffull; // quietize y
746 res = y;
747 } else {
748 // will return x (which is not NaN)
749 res = x;
200359e8 750 }
200359e8
L
751 BID_RETURN (res);
752 }
753 // SIMPLE (CASE2)
754 // if all the bits are the same, these numbers are equal, return either number
755 if (x == y) {
756 res = x;
757 BID_RETURN (res);
758 }
759 // INFINITY (CASE3)
760 if ((x & MASK_INF) == MASK_INF) {
761 // x is infinity, its magnitude is greater than or equal to y
762 // return y as long as x isn't negative infinity
763 res = ((x & MASK_SIGN) == MASK_SIGN
764 && (y & MASK_INF) == MASK_INF) ? y : x;
765 BID_RETURN (res);
766 } else if ((y & MASK_INF) == MASK_INF) {
767 // y is infinity, then it must be greater in magnitude
768 res = y;
769 BID_RETURN (res);
770 }
771 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
772 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
773 exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
774 sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
200359e8
L
775 } else {
776 exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
777 sig_x = (x & MASK_BINARY_SIG1);
200359e8
L
778 }
779
780 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
781 if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
782 exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
783 sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
200359e8
L
784 } else {
785 exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
786 sig_y = (y & MASK_BINARY_SIG1);
200359e8
L
787 }
788
789 // ZERO (CASE4)
790 // some properties:
791 // (+ZERO == -ZERO) => therefore
792 // ignore the sign, and neither number is greater
793 // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
794 // ignore the exponent field
795 // (Any non-canonical # is considered 0)
b2a00c89
L
796 if (sig_x == 0) {
797 res = y; // x_is_zero, its magnitude must be smaller than y
200359e8
L
798 BID_RETURN (res);
799 }
b2a00c89
L
800 if (sig_y == 0) {
801 res = x; // y_is_zero, its magnitude must be smaller than x
200359e8
L
802 BID_RETURN (res);
803 }
804 // REDUNDANT REPRESENTATIONS (CASE6)
805 // if both components are either bigger or smaller,
806 // it is clear what needs to be done
807 if (sig_x > sig_y && exp_x >= exp_y) {
808 res = x;
809 BID_RETURN (res);
810 }
811 if (sig_x < sig_y && exp_x <= exp_y) {
812 res = y;
813 BID_RETURN (res);
814 }
815 // if exp_x is 15 greater than exp_y, no need for compensation
816 if (exp_x - exp_y > 15) {
b2a00c89 817 res = x; // difference cannot be greater than 10^15
200359e8
L
818 BID_RETURN (res);
819 }
820 // if exp_x is 15 less than exp_y, no need for compensation
821 if (exp_y - exp_x > 15) {
822 res = y;
823 BID_RETURN (res);
824 }
825 // if |exp_x - exp_y| < 15, it comes down to the compensated significand
b2a00c89 826 if (exp_x > exp_y) { // to simplify the loop below,
200359e8
L
827 // otherwise adjust the x significand upwards
828 __mul_64x64_to_128MACH (sig_n_prime, sig_x,
829 mult_factor[exp_x - exp_y]);
830 // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y),
831 // this is the compensated signif.
832 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
833 // two numbers are equal, return maxNum(x,y)
834 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
835 BID_RETURN (res);
836 }
837 // now, if compensated_x (sig_n_prime) is greater than y return y,
838 // otherwise return x
839 res = ((sig_n_prime.w[1] != 0) || sig_n_prime.w[0] > sig_y) ? x : y;
840 BID_RETURN (res);
841 }
842 // exp_y must be greater than exp_x, thus adjust the y significand upwards
843 __mul_64x64_to_128MACH (sig_n_prime, sig_y,
844 mult_factor[exp_y - exp_x]);
845
846 if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
b2a00c89
L
847 res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
848 // two numbers are equal, return either
200359e8
L
849 BID_RETURN (res);
850 }
851
852 res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? x : y;
853 BID_RETURN (res);
854}