1 /* Copyright (C) 2007 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
10 In addition to the permissions in the GNU General Public License, the
11 Free Software Foundation gives you unlimited permission to link the
12 compiled version of this file into combinations with other programs,
13 and to distribute those combinations without any restriction coming
14 from the use of this file. (The General Public License restrictions
15 do apply in other respects; for example, they cover modification of
16 the file, and distribution when not linked into a combine
19 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 You should have received a copy of the GNU General Public License
25 along with GCC; see the file COPYING. If not, write to the Free
26 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29 #include "bid_internal.h"
31 /*****************************************************************************
33 ****************************************************************************/
35 #if DECIMAL_CALL_BY_REFERENCE
37 bid64_nextup (UINT64 * pres,
39 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
43 bid64_nextup (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
53 UINT64 C1; // C1 represents x_signif (UINT64)
55 // check for NaNs and infinities
56 if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
57 if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
58 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
60 x = x & 0xfe03ffffffffffffull; // clear G6-G12
61 if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
63 *pfpsf |= INVALID_EXCEPTION;
64 // return quiet (SNaN)
65 res = x & 0xfdffffffffffffffull;
70 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
71 if (!(x & 0x8000000000000000ull)) { // x is +inf
72 res = 0x7800000000000000ull;
74 res = 0xf7fb86f26fc0ffffull; // -MAXFP = -999...99 * 10^emax
78 // unpack the argument
79 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
80 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
81 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
82 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
83 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
84 if (C1 > 9999999999999999ull) { // non-canonical
89 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
90 C1 = x & MASK_BINARY_SIG1;
93 // check for zeros (possibly from non-canonical values)
96 res = 0x0000000000000001ull; // MINFP = 1 * 10^emin
97 } else { // x is not special and is not zero
98 if (x == 0x77fb86f26fc0ffffull) {
99 // x = +MAXFP = 999...99 * 10^emax
100 res = 0x7800000000000000ull; // +inf
101 } else if (x == 0x8000000000000001ull) {
102 // x = -MINFP = 1...99 * 10^emin
103 res = 0x8000000000000000ull; // -0
104 } else { // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
105 // can add/subtract 1 ulp to the significand
107 // Note: we could check here if x >= 10^16 to speed up the case q1 =16
108 // q1 = nr. of decimal digits in x (1 <= q1 <= 54)
109 // determine first the nr. of bits in x
110 if (C1 >= MASK_BINARY_OR2) { // x >= 2^53
111 // split the 64-bit value in two 32-bit halves to avoid rounding errors
112 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
113 tmp1.d = (double) (C1 >> 32); // exact conversion
115 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
117 tmp1.d = (double) C1; // exact conversion
119 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
121 } else { // if x < 2^53
122 tmp1.d = (double) C1; // exact conversion
124 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
126 q1 = nr_digits[x_nr_bits - 1].digits;
128 q1 = nr_digits[x_nr_bits - 1].digits1;
129 if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
132 // if q1 < P16 then pad the significand with zeros
134 if (x_exp > (UINT64) (P16 - q1)) {
135 ind = P16 - q1; // 1 <= ind <= P16 - 1
136 // pad with P16 - q1 zeros, until exponent = emin
138 C1 = C1 * ten2k64[ind];
140 } else { // pad with zeros until the exponent reaches emin
142 C1 = C1 * ten2k64[ind];
146 if (!x_sign) { // x > 0
147 // add 1 ulp (add 1 to the significand)
149 if (C1 == 0x002386f26fc10000ull) { // if C1 = 10^16
150 C1 = 0x00038d7ea4c68000ull; // C1 = 10^15
153 // Ok, because MAXFP = 999...99 * 10^emax was caught already
155 // subtract 1 ulp (subtract 1 from the significand)
157 if (C1 == 0x00038d7ea4c67fffull && x_exp != 0) { // if C1 = 10^15 - 1
158 C1 = 0x002386f26fc0ffffull; // C1 = 10^16 - 1
162 // assemble the result
163 // if significand has 54 bits
164 if (C1 & MASK_BINARY_OR2) {
166 x_sign | (x_exp << 51) | MASK_STEERING_BITS | (C1 &
168 } else { // significand fits in 53 bits
169 res = x_sign | (x_exp << 53) | C1;
171 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
172 } // end x is not special and is not zero
176 /*****************************************************************************
178 ****************************************************************************/
180 #if DECIMAL_CALL_BY_REFERENCE
182 bid64_nextdown (UINT64 * pres,
184 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
188 bid64_nextdown (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
198 UINT64 C1; // C1 represents x_signif (UINT64)
200 // check for NaNs and infinities
201 if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
202 if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
203 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
205 x = x & 0xfe03ffffffffffffull; // clear G6-G12
206 if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
208 *pfpsf |= INVALID_EXCEPTION;
209 // return quiet (SNaN)
210 res = x & 0xfdffffffffffffffull;
215 } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
216 if (x & 0x8000000000000000ull) { // x is -inf
217 res = 0xf800000000000000ull;
218 } else { // x is +inf
219 res = 0x77fb86f26fc0ffffull; // +MAXFP = +999...99 * 10^emax
223 // unpack the argument
224 x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
225 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
226 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
227 x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
228 C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
229 if (C1 > 9999999999999999ull) { // non-canonical
234 x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
235 C1 = x & MASK_BINARY_SIG1;
238 // check for zeros (possibly from non-canonical values)
241 res = 0x8000000000000001ull; // -MINFP = -1 * 10^emin
242 } else { // x is not special and is not zero
243 if (x == 0xf7fb86f26fc0ffffull) {
244 // x = -MAXFP = -999...99 * 10^emax
245 res = 0xf800000000000000ull; // -inf
246 } else if (x == 0x0000000000000001ull) {
247 // x = +MINFP = 1...99 * 10^emin
248 res = 0x0000000000000000ull; // -0
249 } else { // -MAXFP + 1ulp <= x <= -MINFP OR MINFP + 1 ulp <= x <= MAXFP
250 // can add/subtract 1 ulp to the significand
252 // Note: we could check here if x >= 10^16 to speed up the case q1 =16
253 // q1 = nr. of decimal digits in x (1 <= q1 <= 16)
254 // determine first the nr. of bits in x
255 if (C1 >= 0x0020000000000000ull) { // x >= 2^53
256 // split the 64-bit value in two 32-bit halves to avoid
258 if (C1 >= 0x0000000100000000ull) { // x >= 2^32
259 tmp1.d = (double) (C1 >> 32); // exact conversion
261 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
263 tmp1.d = (double) C1; // exact conversion
265 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
267 } else { // if x < 2^53
268 tmp1.d = (double) C1; // exact conversion
270 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
272 q1 = nr_digits[x_nr_bits - 1].digits;
274 q1 = nr_digits[x_nr_bits - 1].digits1;
275 if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
278 // if q1 < P16 then pad the significand with zeros
280 if (x_exp > (UINT64) (P16 - q1)) {
281 ind = P16 - q1; // 1 <= ind <= P16 - 1
282 // pad with P16 - q1 zeros, until exponent = emin
284 C1 = C1 * ten2k64[ind];
286 } else { // pad with zeros until the exponent reaches emin
288 C1 = C1 * ten2k64[ind];
292 if (x_sign) { // x < 0
293 // add 1 ulp (add 1 to the significand)
295 if (C1 == 0x002386f26fc10000ull) { // if C1 = 10^16
296 C1 = 0x00038d7ea4c68000ull; // C1 = 10^15
298 // Ok, because -MAXFP = -999...99 * 10^emax was caught already
301 // subtract 1 ulp (subtract 1 from the significand)
303 if (C1 == 0x00038d7ea4c67fffull && x_exp != 0) { // if C1 = 10^15 - 1
304 C1 = 0x002386f26fc0ffffull; // C1 = 10^16 - 1
308 // assemble the result
309 // if significand has 54 bits
310 if (C1 & MASK_BINARY_OR2) {
312 x_sign | (x_exp << 51) | MASK_STEERING_BITS | (C1 &
314 } else { // significand fits in 53 bits
315 res = x_sign | (x_exp << 53) | C1;
317 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
318 } // end x is not special and is not zero
322 /*****************************************************************************
324 ****************************************************************************/
326 #if DECIMAL_CALL_BY_REFERENCE
328 bid64_nextafter (UINT64 * pres, UINT64 * px,
330 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
335 bid64_nextafter (UINT64 x,
336 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
342 FPSC tmp_fpsf = 0; // dummy fpsf for calls to comparison functions
345 // check for NaNs or infinities
346 if (((x & MASK_SPECIAL) == MASK_SPECIAL) ||
347 ((y & MASK_SPECIAL) == MASK_SPECIAL)) {
348 // x is NaN or infinity or y is NaN or infinity
350 if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
351 if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
352 x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
354 x = x & 0xfe03ffffffffffffull; // clear G6-G12
355 if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNAN
357 *pfpsf |= INVALID_EXCEPTION;
359 res = x & 0xfdffffffffffffffull;
360 } else { // x is QNaN
361 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
363 *pfpsf |= INVALID_EXCEPTION;
369 } else if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
370 if ((y & 0x0003ffffffffffffull) > 999999999999999ull)
371 y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
373 y = y & 0xfe03ffffffffffffull; // clear G6-G12
374 if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
376 *pfpsf |= INVALID_EXCEPTION;
378 res = y & 0xfdffffffffffffffull;
379 } else { // y is QNaN
384 } else { // at least one is infinity
385 if ((x & MASK_ANY_INF) == MASK_INF) { // x = inf
386 x = x & (MASK_SIGN | MASK_INF);
388 if ((y & MASK_ANY_INF) == MASK_INF) { // y = inf
389 y = y & (MASK_SIGN | MASK_INF);
393 // neither x nor y is NaN
395 // if not infinity, check for non-canonical values x (treated as zero)
396 if ((x & MASK_ANY_INF) != MASK_INF) { // x != inf
398 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
399 // if the steering bits are 11 (condition will be 0), then
400 // the exponent is G[0:w+1]
401 if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
402 9999999999999999ull) {
404 x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
406 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS) x is unch.
410 // no need to check for non-canonical y
412 // neither x nor y is NaN
413 tmp_fpsf = *pfpsf; // save fpsf
414 #if DECIMAL_CALL_BY_REFERENCE
415 bid64_quiet_equal (&res1, px,
416 py _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
417 bid64_quiet_greater (&res2, px,
418 py _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
421 bid64_quiet_equal (x,
422 y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
424 bid64_quiet_greater (x,
425 y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
427 *pfpsf = tmp_fpsf; // restore fpsf
429 // return x with the sign of y
430 res = (y & 0x8000000000000000ull) | (x & 0x7fffffffffffffffull);
431 } else if (res2) { // x > y
432 #if DECIMAL_CALL_BY_REFERENCE
433 bid64_nextdown (&res,
434 px _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
437 bid64_nextdown (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
440 #if DECIMAL_CALL_BY_REFERENCE
441 bid64_nextup (&res, px _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
443 res = bid64_nextup (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
446 // if the operand x is finite but the result is infinite, signal
447 // overflow and inexact
448 if (((x & MASK_INF) != MASK_INF) && ((res & MASK_INF) == MASK_INF)) {
449 // set the inexact flag
450 *pfpsf |= INEXACT_EXCEPTION;
451 // set the overflow flag
452 *pfpsf |= OVERFLOW_EXCEPTION;
454 // if the result is in (-10^emin, 10^emin), and is different from the
455 // operand x, signal underflow and inexact
456 tmp1 = 0x00038d7ea4c68000ull; // +100...0[16] * 10^emin
457 tmp2 = res & 0x7fffffffffffffffull;
458 tmp_fpsf = *pfpsf; // save fpsf
459 #if DECIMAL_CALL_BY_REFERENCE
460 bid64_quiet_greater (&res1, &tmp1,
461 &tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
463 bid64_quiet_not_equal (&res2, &x,
464 &res _EXC_FLAGS_ARG _EXC_MASKS_ARG
468 bid64_quiet_greater (tmp1,
469 tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
472 bid64_quiet_not_equal (x,
473 res _EXC_FLAGS_ARG _EXC_MASKS_ARG
476 *pfpsf = tmp_fpsf; // restore fpsf
478 // if (bid64_quiet_greater (tmp1, tmp2, &tmp_fpsf) &&
479 // bid64_quiet_not_equal (x, res, &tmp_fpsf)) {
480 // set the inexact flag
481 *pfpsf |= INEXACT_EXCEPTION;
482 // set the underflow flag
483 *pfpsf |= UNDERFLOW_EXCEPTION;