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
30 #include "bid_internal.h"
32 /*****************************************************************************
34 ****************************************************************************/
36 #if DECIMAL_CALL_BY_REFERENCE
38 bid128_nextup (UINT128
* pres
,
40 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
44 bid128_nextup (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
55 UINT128 C1
; // C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
58 // unpack the argument
59 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
60 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
63 // check for NaN or Infinity
64 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
66 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
67 // if x = NaN, then res = Q (x)
68 // check first for non-canonical NaN payload
69 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
70 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
)
71 && (x
.w
[0] > 0x38c15b09ffffffffull
))) {
72 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
75 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
77 *pfpsf
|= INVALID_EXCEPTION
;
79 res
.w
[1] = x
.w
[1] & 0xfc003fffffffffffull
; // clear out also G[6]-G[16]
83 res
.w
[1] = x
.w
[1] & 0xfc003fffffffffffull
; // clear out G[6]-G[16]
86 } else { // x is not NaN, so it must be infinity
87 if (!x_sign
) { // x is +inf
88 res
.w
[1] = 0x7800000000000000ull
; // +inf
89 res
.w
[0] = 0x0000000000000000ull
;
91 res
.w
[1] = 0xdfffed09bead87c0ull
; // -MAXFP = -999...99 * 10^emax
92 res
.w
[0] = 0x378d8e63ffffffffull
;
97 // check for non-canonical values (treated as zero)
98 if ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) { // G0_G1=11
100 x_exp
= (x
.w
[1] << 2) & MASK_EXP
; // biased and shifted left 49 bits
101 C1
.w
[1] = 0; // significand high
102 C1
.w
[0] = 0; // significand low
103 } else { // G0_G1 != 11
104 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bits
105 if (C1
.w
[1] > 0x0001ed09bead87c0ull
||
106 (C1
.w
[1] == 0x0001ed09bead87c0ull
107 && C1
.w
[0] > 0x378d8e63ffffffffull
)) {
108 // x is non-canonical if coefficient is larger than 10^34 -1
111 } else { // canonical
116 if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
118 res
.w
[1] = 0x0000000000000000ull
; // +1 * 10^emin
119 res
.w
[0] = 0x0000000000000001ull
;
120 } else { // x is not special and is not zero
121 if (x
.w
[1] == 0x5fffed09bead87c0ull
122 && x
.w
[0] == 0x378d8e63ffffffffull
) {
123 // x = +MAXFP = 999...99 * 10^emax
124 res
.w
[1] = 0x7800000000000000ull
; // +inf
125 res
.w
[0] = 0x0000000000000000ull
;
126 } else if (x
.w
[1] == 0x8000000000000000ull
127 && x
.w
[0] == 0x0000000000000001ull
) {
128 // x = -MINFP = 1...99 * 10^emin
129 res
.w
[1] = 0x8000000000000000ull
; // -0
130 res
.w
[0] = 0x0000000000000000ull
;
131 } else { // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
132 // can add/subtract 1 ulp to the significand
134 // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
135 // q1 = nr. of decimal digits in x
136 // determine first the nr. of bits in x
138 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
139 // split the 64-bit value in two 32-bit halves to avoid rnd errors
140 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
141 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
143 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) -
146 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
148 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) -
151 } else { // if x < 2^53
152 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
154 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
156 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
157 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
159 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
161 q1
= nr_digits
[x_nr_bits
- 1].digits
;
163 q1
= nr_digits
[x_nr_bits
- 1].digits1
;
164 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
165 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
166 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
169 // if q1 < P34 then pad the significand with zeros
171 exp
= (x_exp
>> 49) - 6176;
172 if (exp
+ 6176 > P34
- q1
) {
173 ind
= P34
- q1
; // 1 <= ind <= P34 - 1
174 // pad with P34 - q1 zeros, until exponent = emin
176 if (q1
<= 19) { // 64-bit C1
177 if (ind
<= 19) { // 64-bit 10^ind and 64-bit C1
178 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[ind
]);
179 } else { // 128-bit 10^ind and 64-bit C1
180 __mul_128x64_to_128 (C1
, C1
.w
[0], ten2k128
[ind
- 20]);
182 } else { // C1 is (most likely) 128-bit
183 if (ind
<= 14) { // 64-bit 10^ind and 128-bit C1 (most likely)
184 __mul_128x64_to_128 (C1
, ten2k64
[ind
], C1
);
185 } else if (ind
<= 19) { // 64-bit 10^ind and 64-bit C1 (q1 <= 19)
186 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[ind
]);
187 } else { // 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
188 __mul_128x64_to_128 (C1
, C1
.w
[0], ten2k128
[ind
- 20]);
191 x_exp
= x_exp
- ((UINT64
) ind
<< 49);
192 } else { // pad with zeros until the exponent reaches emin
195 if (ind
<= 19) { // 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
196 if (q1
<= 19) { // 64-bit C1, 64-bit 10^ind
197 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[ind
]);
198 } else { // 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
199 __mul_128x64_to_128 (C1
, ten2k64
[ind
], C1
);
201 } else { // if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
202 // 64-bit C1, 128-bit 10^ind
203 __mul_128x64_to_128 (C1
, C1
.w
[0], ten2k128
[ind
- 20]);
208 if (!x_sign
) { // x > 0
209 // add 1 ulp (add 1 to the significand)
213 if (C1
.w
[1] == 0x0001ed09bead87c0ull
&& C1
.w
[0] == 0x378d8e6400000000ull
) { // if C1 = 10^34
214 C1
.w
[1] = 0x0000314dc6448d93ull
; // C1 = 10^33
215 C1
.w
[0] = 0x38c15b0a00000000ull
;
216 x_exp
= x_exp
+ EXP_P1
;
219 // subtract 1 ulp (subtract 1 from the significand)
221 if (C1
.w
[0] == 0xffffffffffffffffull
)
223 if (x_exp
!= 0 && C1
.w
[1] == 0x0000314dc6448d93ull
&& C1
.w
[0] == 0x38c15b09ffffffffull
) { // if C1 = 10^33 - 1
224 C1
.w
[1] = 0x0001ed09bead87c0ull
; // C1 = 10^34 - 1
225 C1
.w
[0] = 0x378d8e63ffffffffull
;
226 x_exp
= x_exp
- EXP_P1
;
229 // assemble the result
230 res
.w
[1] = x_sign
| x_exp
| C1
.w
[1];
232 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
233 } // end x is not special and is not zero
237 /*****************************************************************************
239 ****************************************************************************/
241 #if DECIMAL_CALL_BY_REFERENCE
243 bid128_nextdown (UINT128
* pres
,
245 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
) {
249 bid128_nextdown (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
260 UINT128 C1
; // C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
263 // unpack the argument
264 x_sign
= x
.w
[1] & MASK_SIGN
; // 0 for positive, MASK_SIGN for negative
265 C1
.w
[1] = x
.w
[1] & MASK_COEFF
;
268 // check for NaN or Infinity
269 if ((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
) {
271 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
272 // if x = NaN, then res = Q (x)
273 // check first for non-canonical NaN payload
274 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
275 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
)
276 && (x
.w
[0] > 0x38c15b09ffffffffull
))) {
277 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
280 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
282 *pfpsf
|= INVALID_EXCEPTION
;
284 res
.w
[1] = x
.w
[1] & 0xfc003fffffffffffull
; // clear out also G[6]-G[16]
286 } else { // x is QNaN
288 res
.w
[1] = x
.w
[1] & 0xfc003fffffffffffull
; // clear out G[6]-G[16]
291 } else { // x is not NaN, so it must be infinity
292 if (!x_sign
) { // x is +inf
293 res
.w
[1] = 0x5fffed09bead87c0ull
; // +MAXFP = +999...99 * 10^emax
294 res
.w
[0] = 0x378d8e63ffffffffull
;
295 } else { // x is -inf
296 res
.w
[1] = 0xf800000000000000ull
; // -inf
297 res
.w
[0] = 0x0000000000000000ull
;
302 // check for non-canonical values (treated as zero)
303 if ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) { // G0_G1=11
305 x_exp
= (x
.w
[1] << 2) & MASK_EXP
; // biased and shifted left 49 bits
306 C1
.w
[1] = 0; // significand high
307 C1
.w
[0] = 0; // significand low
308 } else { // G0_G1 != 11
309 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bits
310 if (C1
.w
[1] > 0x0001ed09bead87c0ull
||
311 (C1
.w
[1] == 0x0001ed09bead87c0ull
312 && C1
.w
[0] > 0x378d8e63ffffffffull
)) {
313 // x is non-canonical if coefficient is larger than 10^34 -1
316 } else { // canonical
321 if ((C1
.w
[1] == 0x0ull
) && (C1
.w
[0] == 0x0ull
)) {
323 res
.w
[1] = 0x8000000000000000ull
; // -1 * 10^emin
324 res
.w
[0] = 0x0000000000000001ull
;
325 } else { // x is not special and is not zero
326 if (x
.w
[1] == 0xdfffed09bead87c0ull
327 && x
.w
[0] == 0x378d8e63ffffffffull
) {
328 // x = -MAXFP = -999...99 * 10^emax
329 res
.w
[1] = 0xf800000000000000ull
; // -inf
330 res
.w
[0] = 0x0000000000000000ull
;
331 } else if (x
.w
[1] == 0x0ull
&& x
.w
[0] == 0x0000000000000001ull
) { // +MINFP
332 res
.w
[1] = 0x0000000000000000ull
; // +0
333 res
.w
[0] = 0x0000000000000000ull
;
334 } else { // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
335 // can add/subtract 1 ulp to the significand
337 // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
338 // q1 = nr. of decimal digits in x
339 // determine first the nr. of bits in x
341 if (C1
.w
[0] >= 0x0020000000000000ull
) { // x >= 2^53
342 // split the 64-bit value in two 32-bit halves to avoid rnd errors
343 if (C1
.w
[0] >= 0x0000000100000000ull
) { // x >= 2^32
344 tmp1
.d
= (double) (C1
.w
[0] >> 32); // exact conversion
346 33 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) -
349 tmp1
.d
= (double) (C1
.w
[0]); // exact conversion
351 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) -
354 } else { // if x < 2^53
355 tmp1
.d
= (double) C1
.w
[0]; // exact conversion
357 1 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
359 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
360 tmp1
.d
= (double) C1
.w
[1]; // exact conversion
362 65 + ((((unsigned int) (tmp1
.ui64
>> 52)) & 0x7ff) - 0x3ff);
364 q1
= nr_digits
[x_nr_bits
- 1].digits
;
366 q1
= nr_digits
[x_nr_bits
- 1].digits1
;
367 if (C1
.w
[1] > nr_digits
[x_nr_bits
- 1].threshold_hi
368 || (C1
.w
[1] == nr_digits
[x_nr_bits
- 1].threshold_hi
369 && C1
.w
[0] >= nr_digits
[x_nr_bits
- 1].threshold_lo
))
372 // if q1 < P then pad the significand with zeros
374 exp
= (x_exp
>> 49) - 6176;
375 if (exp
+ 6176 > P34
- q1
) {
376 ind
= P34
- q1
; // 1 <= ind <= P34 - 1
377 // pad with P34 - q1 zeros, until exponent = emin
379 if (q1
<= 19) { // 64-bit C1
380 if (ind
<= 19) { // 64-bit 10^ind and 64-bit C1
381 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[ind
]);
382 } else { // 128-bit 10^ind and 64-bit C1
383 __mul_128x64_to_128 (C1
, C1
.w
[0], ten2k128
[ind
- 20]);
385 } else { // C1 is (most likely) 128-bit
386 if (ind
<= 14) { // 64-bit 10^ind and 128-bit C1 (most likely)
387 __mul_128x64_to_128 (C1
, ten2k64
[ind
], C1
);
388 } else if (ind
<= 19) { // 64-bit 10^ind and 64-bit C1 (q1 <= 19)
389 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[ind
]);
390 } else { // 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
391 __mul_128x64_to_128 (C1
, C1
.w
[0], ten2k128
[ind
- 20]);
394 x_exp
= x_exp
- ((UINT64
) ind
<< 49);
395 } else { // pad with zeros until the exponent reaches emin
398 if (ind
<= 19) { // 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
399 if (q1
<= 19) { // 64-bit C1, 64-bit 10^ind
400 __mul_64x64_to_128MACH (C1
, C1
.w
[0], ten2k64
[ind
]);
401 } else { // 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
402 __mul_128x64_to_128 (C1
, ten2k64
[ind
], C1
);
404 } else { // if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
405 // 64-bit C1, 128-bit 10^ind
406 __mul_128x64_to_128 (C1
, C1
.w
[0], ten2k128
[ind
- 20]);
411 if (x_sign
) { // x < 0
412 // add 1 ulp (add 1 to the significand)
416 if (C1
.w
[1] == 0x0001ed09bead87c0ull
&& C1
.w
[0] == 0x378d8e6400000000ull
) { // if C1 = 10^34
417 C1
.w
[1] = 0x0000314dc6448d93ull
; // C1 = 10^33
418 C1
.w
[0] = 0x38c15b0a00000000ull
;
419 x_exp
= x_exp
+ EXP_P1
;
422 // subtract 1 ulp (subtract 1 from the significand)
424 if (C1
.w
[0] == 0xffffffffffffffffull
)
426 if (x_exp
!= 0 && C1
.w
[1] == 0x0000314dc6448d93ull
&& C1
.w
[0] == 0x38c15b09ffffffffull
) { // if C1 = 10^33 - 1
427 C1
.w
[1] = 0x0001ed09bead87c0ull
; // C1 = 10^34 - 1
428 C1
.w
[0] = 0x378d8e63ffffffffull
;
429 x_exp
= x_exp
- EXP_P1
;
432 // assemble the result
433 res
.w
[1] = x_sign
| x_exp
| C1
.w
[1];
435 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
436 } // end x is not special and is not zero
440 /*****************************************************************************
442 ****************************************************************************/
444 #if DECIMAL_CALL_BY_REFERENCE
446 bid128_nextafter (UINT128
* pres
, UINT128
* px
,
448 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM
)
456 bid128_nextafter (UINT128 x
,
457 UINT128 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
464 UINT128 tmp1
, tmp2
, tmp3
;
465 FPSC tmp_fpsf
= 0; // dummy fpsf for calls to comparison functions
473 if (((x
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
)
474 || ((y
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
)) {
475 // x is special or y is special
476 if ((x
.w
[1] & MASK_NAN
) == MASK_NAN
) { // x is NAN
477 // if x = NaN, then res = Q (x)
478 // check first for non-canonical NaN payload
479 if (((x
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
480 (((x
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
)
481 && (x
.w
[0] > 0x38c15b09ffffffffull
))) {
482 x
.w
[1] = x
.w
[1] & 0xffffc00000000000ull
;
485 if ((x
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // x is SNAN
487 *pfpsf
|= INVALID_EXCEPTION
;
489 res
.w
[1] = x
.w
[1] & 0xfc003fffffffffffull
; // clear out also G[6]-G[16]
491 } else { // x is QNaN
493 res
.w
[1] = x
.w
[1] & 0xfc003fffffffffffull
; // clear out G[6]-G[16]
495 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
497 *pfpsf
|= INVALID_EXCEPTION
;
501 } else if ((y
.w
[1] & MASK_NAN
) == MASK_NAN
) { // y is NAN
502 // if x = NaN, then res = Q (x)
503 // check first for non-canonical NaN payload
504 if (((y
.w
[1] & 0x00003fffffffffffull
) > 0x0000314dc6448d93ull
) ||
505 (((y
.w
[1] & 0x00003fffffffffffull
) == 0x0000314dc6448d93ull
)
506 && (y
.w
[0] > 0x38c15b09ffffffffull
))) {
507 y
.w
[1] = y
.w
[1] & 0xffffc00000000000ull
;
510 if ((y
.w
[1] & MASK_SNAN
) == MASK_SNAN
) { // y is SNAN
512 *pfpsf
|= INVALID_EXCEPTION
;
514 res
.w
[1] = y
.w
[1] & 0xfc003fffffffffffull
; // clear out also G[6]-G[16]
516 } else { // x is QNaN
518 res
.w
[1] = y
.w
[1] & 0xfc003fffffffffffull
; // clear out G[6]-G[16]
522 } else { // at least one is infinity
523 if ((x
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // x = inf
524 x
.w
[1] = x
.w
[1] & (MASK_SIGN
| MASK_INF
);
527 if ((y
.w
[1] & MASK_ANY_INF
) == MASK_INF
) { // y = inf
528 y
.w
[1] = y
.w
[1] & (MASK_SIGN
| MASK_INF
);
533 // neither x nor y is NaN
535 // if not infinity, check for non-canonical values x (treated as zero)
536 if ((x
.w
[1] & MASK_ANY_INF
) != MASK_INF
) { // x != inf
537 if ((x
.w
[1] & 0x6000000000000000ull
) == 0x6000000000000000ull
) { // G0_G1=11
539 x_exp
= (x
.w
[1] << 2) & MASK_EXP
; // biased and shifted left 49 bits
540 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | x_exp
;
542 } else { // G0_G1 != 11
543 x_exp
= x
.w
[1] & MASK_EXP
; // biased and shifted left 49 bits
544 if ((x
.w
[1] & MASK_COEFF
) > 0x0001ed09bead87c0ull
||
545 ((x
.w
[1] & MASK_COEFF
) == 0x0001ed09bead87c0ull
546 && x
.w
[0] > 0x378d8e63ffffffffull
)) {
547 // x is non-canonical if coefficient is larger than 10^34 -1
548 x
.w
[1] = (x
.w
[1] & MASK_SIGN
) | x_exp
;
550 } else { // canonical
555 // no need to check for non-canonical y
557 // neither x nor y is NaN
558 tmp_fpsf
= *pfpsf
; // save fpsf
559 #if DECIMAL_CALL_BY_REFERENCE
560 bid128_quiet_equal (&res1
, &xnswp
,
561 &ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
563 bid128_quiet_greater (&res2
, &xnswp
,
564 &ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
568 bid128_quiet_equal (xnswp
,
569 ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
572 bid128_quiet_greater (xnswp
,
573 ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
576 *pfpsf
= tmp_fpsf
; // restore fpsf
579 // return x with the sign of y
581 (x
.w
[1] & 0x7fffffffffffffffull
) | (y
.
582 w
[1] & 0x8000000000000000ull
);
584 } else if (res2
) { // x > y
585 #if DECIMAL_CALL_BY_REFERENCE
586 bid128_nextdown (&res
,
587 &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
591 bid128_nextdown (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
596 #if DECIMAL_CALL_BY_REFERENCE
598 &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
601 bid128_nextup (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG
);
605 // if the operand x is finite but the result is infinite, signal
606 // overflow and inexact
607 if (((x
.w
[1] & MASK_SPECIAL
) != MASK_SPECIAL
)
608 && ((res
.w
[1] & MASK_SPECIAL
) == MASK_SPECIAL
)) {
609 // set the inexact flag
610 *pfpsf
|= INEXACT_EXCEPTION
;
611 // set the overflow flag
612 *pfpsf
|= OVERFLOW_EXCEPTION
;
614 // if the result is in (-10^emin, 10^emin), and is different from the
615 // operand x, signal underflow and inexact
616 tmp1
.w
[HIGH_128W
] = 0x0000314dc6448d93ull
;
617 tmp1
.w
[LOW_128W
] = 0x38c15b0a00000000ull
; // +100...0[34] * 10^emin
618 tmp2
.w
[HIGH_128W
] = res
.w
[1] & 0x7fffffffffffffffull
;
619 tmp2
.w
[LOW_128W
] = res
.w
[0];
620 tmp3
.w
[HIGH_128W
] = res
.w
[1];
621 tmp3
.w
[LOW_128W
] = res
.w
[0];
622 tmp_fpsf
= *pfpsf
; // save fpsf
623 #if DECIMAL_CALL_BY_REFERENCE
624 bid128_quiet_greater (&res1
, &tmp1
,
625 &tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
627 bid128_quiet_not_equal (&res2
, &xnswp
,
628 &tmp3 _EXC_FLAGS_ARG _EXC_MASKS_ARG
632 bid128_quiet_greater (tmp1
,
633 tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
636 bid128_quiet_not_equal (xnswp
,
637 tmp3 _EXC_FLAGS_ARG _EXC_MASKS_ARG
640 *pfpsf
= tmp_fpsf
; // restore fpsf
642 // set the inexact flag
643 *pfpsf
|= INEXACT_EXCEPTION
;
644 // set the underflow flag
645 *pfpsf
|= UNDERFLOW_EXCEPTION
;