1 /* Copyright (C) 2007-2016 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 3, or (at your option) any later
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
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.
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/>. */
24 #include "bid_internal.h"
26 /*****************************************************************************
28 ****************************************************************************/
30 #if DECIMAL_CALL_BY_REFERENCE
32 bid64_nextup (UINT64
* pres
,
34 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
38 bid64_nextup (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
48 UINT64 C1
; // C1 represents x_signif (UINT64)
50 // check for NaNs and infinities
51 if ((x
& MASK_NAN
) == MASK_NAN
) { // check for NaN
52 if ((x
& 0x0003ffffffffffffull
) > 999999999999999ull)
53 x
= x
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
55 x
= x
& 0xfe03ffffffffffffull
; // clear G6-G12
56 if ((x
& MASK_SNAN
) == MASK_SNAN
) { // SNaN
58 *pfpsf
|= INVALID_EXCEPTION
;
59 // return quiet (SNaN)
60 res
= x
& 0xfdffffffffffffffull
;
65 } else if ((x
& MASK_INF
) == MASK_INF
) { // check for Infinity
66 if (!(x
& 0x8000000000000000ull
)) { // x is +inf
67 res
= 0x7800000000000000ull
;
69 res
= 0xf7fb86f26fc0ffffull
; // -MAXFP = -999...99 * 10^emax
73 // unpack the argument
74 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
75 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
76 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
77 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
78 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
79 if (C1
> 9999999999999999ull) { // non-canonical
84 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
85 C1
= x
& MASK_BINARY_SIG1
;
88 // check for zeros (possibly from non-canonical values)
91 res
= 0x0000000000000001ull
; // MINFP = 1 * 10^emin
92 } else { // x is not special and is not zero
93 if (x
== 0x77fb86f26fc0ffffull
) {
94 // x = +MAXFP = 999...99 * 10^emax
95 res
= 0x7800000000000000ull
; // +inf
96 } else if (x
== 0x8000000000000001ull
) {
97 // x = -MINFP = 1...99 * 10^emin
98 res
= 0x8000000000000000ull
; // -0
99 } else { // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
100 // can add/subtract 1 ulp to the significand
102 // Note: we could check here if x >= 10^16 to speed up the case q1 =16
103 // q1 = nr. of decimal digits in x (1 <= q1 <= 54)
104 // determine first the nr. of bits in x
105 if (C1
>= MASK_BINARY_OR2
) { // x >= 2^53
106 // split the 64-bit value in two 32-bit halves to avoid rounding errors
107 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
108 tmp1
.d
= (double) (C1
>> 32); // exact conversion
110 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
112 tmp1
.d
= (double) C1
; // exact conversion
114 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
116 } else { // if x < 2^53
117 tmp1
.d
= (double) C1
; // exact conversion
119 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
121 q1
= nr_digits
[x_nr_bits
- 1].digits
;
123 q1
= nr_digits
[x_nr_bits
- 1].digits1
;
124 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
127 // if q1 < P16 then pad the significand with zeros
129 if (x_exp
> (UINT64
) (P16
- q1
)) {
130 ind
= P16
- q1
; // 1 <= ind <= P16 - 1
131 // pad with P16 - q1 zeros, until exponent = emin
133 C1
= C1
* ten2k64
[ind
];
135 } else { // pad with zeros until the exponent reaches emin
137 C1
= C1
* ten2k64
[ind
];
141 if (!x_sign
) { // x > 0
142 // add 1 ulp (add 1 to the significand)
144 if (C1
== 0x002386f26fc10000ull
) { // if C1 = 10^16
145 C1
= 0x00038d7ea4c68000ull
; // C1 = 10^15
148 // Ok, because MAXFP = 999...99 * 10^emax was caught already
150 // subtract 1 ulp (subtract 1 from the significand)
152 if (C1
== 0x00038d7ea4c67fffull
&& x_exp
!= 0) { // if C1 = 10^15 - 1
153 C1
= 0x002386f26fc0ffffull
; // C1 = 10^16 - 1
157 // assemble the result
158 // if significand has 54 bits
159 if (C1
& MASK_BINARY_OR2
) {
161 x_sign
| (x_exp
<< 51) | MASK_STEERING_BITS
| (C1
&
163 } else { // significand fits in 53 bits
164 res
= x_sign
| (x_exp
<< 53) | C1
;
166 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
167 } // end x is not special and is not zero
171 /*****************************************************************************
173 ****************************************************************************/
175 #if DECIMAL_CALL_BY_REFERENCE
177 bid64_nextdown (UINT64
* pres
,
179 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
183 bid64_nextdown (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
193 UINT64 C1
; // C1 represents x_signif (UINT64)
195 // check for NaNs and infinities
196 if ((x
& MASK_NAN
) == MASK_NAN
) { // check for NaN
197 if ((x
& 0x0003ffffffffffffull
) > 999999999999999ull)
198 x
= x
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
200 x
= x
& 0xfe03ffffffffffffull
; // clear G6-G12
201 if ((x
& MASK_SNAN
) == MASK_SNAN
) { // SNaN
203 *pfpsf
|= INVALID_EXCEPTION
;
204 // return quiet (SNaN)
205 res
= x
& 0xfdffffffffffffffull
;
210 } else if ((x
& MASK_INF
) == MASK_INF
) { // check for Infinity
211 if (x
& 0x8000000000000000ull
) { // x is -inf
212 res
= 0xf800000000000000ull
;
213 } else { // x is +inf
214 res
= 0x77fb86f26fc0ffffull
; // +MAXFP = +999...99 * 10^emax
218 // unpack the argument
219 x_sign
= x
& MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
220 // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
221 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
222 x_exp
= (x
& MASK_BINARY_EXPONENT2
) >> 51; // biased
223 C1
= (x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
;
224 if (C1
> 9999999999999999ull) { // non-canonical
229 x_exp
= (x
& MASK_BINARY_EXPONENT1
) >> 53; // biased
230 C1
= x
& MASK_BINARY_SIG1
;
233 // check for zeros (possibly from non-canonical values)
236 res
= 0x8000000000000001ull
; // -MINFP = -1 * 10^emin
237 } else { // x is not special and is not zero
238 if (x
== 0xf7fb86f26fc0ffffull
) {
239 // x = -MAXFP = -999...99 * 10^emax
240 res
= 0xf800000000000000ull
; // -inf
241 } else if (x
== 0x0000000000000001ull
) {
242 // x = +MINFP = 1...99 * 10^emin
243 res
= 0x0000000000000000ull
; // -0
244 } else { // -MAXFP + 1ulp <= x <= -MINFP OR MINFP + 1 ulp <= x <= MAXFP
245 // can add/subtract 1 ulp to the significand
247 // Note: we could check here if x >= 10^16 to speed up the case q1 =16
248 // q1 = nr. of decimal digits in x (1 <= q1 <= 16)
249 // determine first the nr. of bits in x
250 if (C1
>= 0x0020000000000000ull
) { // x >= 2^53
251 // split the 64-bit value in two 32-bit halves to avoid
253 if (C1
>= 0x0000000100000000ull
) { // x >= 2^32
254 tmp1
.d
= (double) (C1
>> 32); // exact conversion
256 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
258 tmp1
.d
= (double) C1
; // exact conversion
260 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
262 } else { // if x < 2^53
263 tmp1
.d
= (double) C1
; // exact conversion
265 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
267 q1
= nr_digits
[x_nr_bits
- 1].digits
;
269 q1
= nr_digits
[x_nr_bits
- 1].digits1
;
270 if (C1
>= nr_digits
[x_nr_bits
- 1].threshold_lo
)
273 // if q1 < P16 then pad the significand with zeros
275 if (x_exp
> (UINT64
) (P16
- q1
)) {
276 ind
= P16
- q1
; // 1 <= ind <= P16 - 1
277 // pad with P16 - q1 zeros, until exponent = emin
279 C1
= C1
* ten2k64
[ind
];
281 } else { // pad with zeros until the exponent reaches emin
283 C1
= C1
* ten2k64
[ind
];
287 if (x_sign
) { // x < 0
288 // add 1 ulp (add 1 to the significand)
290 if (C1
== 0x002386f26fc10000ull
) { // if C1 = 10^16
291 C1
= 0x00038d7ea4c68000ull
; // C1 = 10^15
293 // Ok, because -MAXFP = -999...99 * 10^emax was caught already
296 // subtract 1 ulp (subtract 1 from the significand)
298 if (C1
== 0x00038d7ea4c67fffull
&& x_exp
!= 0) { // if C1 = 10^15 - 1
299 C1
= 0x002386f26fc0ffffull
; // C1 = 10^16 - 1
303 // assemble the result
304 // if significand has 54 bits
305 if (C1
& MASK_BINARY_OR2
) {
307 x_sign
| (x_exp
<< 51) | MASK_STEERING_BITS
| (C1
&
309 } else { // significand fits in 53 bits
310 res
= x_sign
| (x_exp
<< 53) | C1
;
312 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
313 } // end x is not special and is not zero
317 /*****************************************************************************
319 ****************************************************************************/
321 #if DECIMAL_CALL_BY_REFERENCE
323 bid64_nextafter (UINT64
* pres
, UINT64
* px
,
325 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
330 bid64_nextafter (UINT64 x
,
331 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
337 FPSC tmp_fpsf
= 0; // dummy fpsf for calls to comparison functions
340 // check for NaNs or infinities
341 if (((x
& MASK_SPECIAL
) == MASK_SPECIAL
) ||
342 ((y
& MASK_SPECIAL
) == MASK_SPECIAL
)) {
343 // x is NaN or infinity or y is NaN or infinity
345 if ((x
& MASK_NAN
) == MASK_NAN
) { // x is NAN
346 if ((x
& 0x0003ffffffffffffull
) > 999999999999999ull)
347 x
= x
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
349 x
= x
& 0xfe03ffffffffffffull
; // clear G6-G12
350 if ((x
& MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
352 *pfpsf
|= INVALID_EXCEPTION
;
354 res
= x
& 0xfdffffffffffffffull
;
355 } else { // x is QNaN
356 if ((y
& MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
358 *pfpsf
|= INVALID_EXCEPTION
;
364 } else if ((y
& MASK_NAN
) == MASK_NAN
) { // y is NAN
365 if ((y
& 0x0003ffffffffffffull
) > 999999999999999ull)
366 y
= y
& 0xfe00000000000000ull
; // clear G6-G12 and the payload bits
368 y
= y
& 0xfe03ffffffffffffull
; // clear G6-G12
369 if ((y
& MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
371 *pfpsf
|= INVALID_EXCEPTION
;
373 res
= y
& 0xfdffffffffffffffull
;
374 } else { // y is QNaN
379 } else { // at least one is infinity
380 if ((x
& MASK_ANY_INF
) == MASK_INF
) { // x = inf
381 x
= x
& (MASK_SIGN
| MASK_INF
);
383 if ((y
& MASK_ANY_INF
) == MASK_INF
) { // y = inf
384 y
= y
& (MASK_SIGN
| MASK_INF
);
388 // neither x nor y is NaN
390 // if not infinity, check for non-canonical values x (treated as zero)
391 if ((x
& MASK_ANY_INF
) != MASK_INF
) { // x != inf
393 if ((x
& MASK_STEERING_BITS
) == MASK_STEERING_BITS
) {
394 // if the steering bits are 11 (condition will be 0), then
395 // the exponent is G[0:w+1]
396 if (((x
& MASK_BINARY_SIG2
) | MASK_BINARY_OR2
) >
397 9999999999999999ull) {
399 x
= (x
& MASK_SIGN
) | ((x
& MASK_BINARY_EXPONENT2
) << 2);
401 } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS) x is unch.
405 // no need to check for non-canonical y
407 // neither x nor y is NaN
408 tmp_fpsf
= *pfpsf
; // save fpsf
409 #if DECIMAL_CALL_BY_REFERENCE
410 bid64_quiet_equal (&res1
, px
,
411 py _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
412 bid64_quiet_greater (&res2
, px
,
413 py _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
416 bid64_quiet_equal (x
,
417 y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
419 bid64_quiet_greater (x
,
420 y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
422 *pfpsf
= tmp_fpsf
; // restore fpsf
424 // return x with the sign of y
425 res
= (y
& 0x8000000000000000ull
) | (x
& 0x7fffffffffffffffull
);
426 } else if (res2
) { // x > y
427 #if DECIMAL_CALL_BY_REFERENCE
428 bid64_nextdown (&res
,
429 px _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
432 bid64_nextdown (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
435 #if DECIMAL_CALL_BY_REFERENCE
436 bid64_nextup (&res
, px _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
438 res
= bid64_nextup (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
441 // if the operand x is finite but the result is infinite, signal
442 // overflow and inexact
443 if (((x
& MASK_INF
) != MASK_INF
) && ((res
& MASK_INF
) == MASK_INF
)) {
444 // set the inexact flag
445 *pfpsf
|= INEXACT_EXCEPTION
;
446 // set the overflow flag
447 *pfpsf
|= OVERFLOW_EXCEPTION
;
449 // if the result is in (-10^emin, 10^emin), and is different from the
450 // operand x, signal underflow and inexact
451 tmp1
= 0x00038d7ea4c68000ull
; // +100...0[16] * 10^emin
452 tmp2
= res
& 0x7fffffffffffffffull
;
453 tmp_fpsf
= *pfpsf
; // save fpsf
454 #if DECIMAL_CALL_BY_REFERENCE
455 bid64_quiet_greater (&res1
, &tmp1
,
456 &tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
458 bid64_quiet_not_equal (&res2
, &x
,
459 &res _EXC_FLAGS_ARG _EXC_MASKS_ARG
463 bid64_quiet_greater (tmp1
,
464 tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
467 bid64_quiet_not_equal (x
,
468 res _EXC_FLAGS_ARG _EXC_MASKS_ARG
471 *pfpsf
= tmp_fpsf
; // restore fpsf
473 // if (bid64_quiet_greater (tmp1, tmp2, &tmp_fpsf) &&
474 // bid64_quiet_not_equal (x, res, &tmp_fpsf)) {
475 // set the inexact flag
476 *pfpsf
|= INEXACT_EXCEPTION
;
477 // set the underflow flag
478 *pfpsf
|= UNDERFLOW_EXCEPTION
;