]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/libbid/bid128_next.c
re PR tree-optimization/33565 (spurious warning: assuming signed overflow does not...
[thirdparty/gcc.git] / libgcc / config / libbid / bid128_next.c
CommitLineData
200359e8
L
1/* Copyright (C) 2007 Free Software Foundation, Inc.
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
7Software Foundation; either version 2, or (at your option) any later
8version.
9
10In addition to the permissions in the GNU General Public License, the
11Free Software Foundation gives you unlimited permission to link the
12compiled version of this file into combinations with other programs,
13and to distribute those combinations without any restriction coming
14from the use of this file. (The General Public License restrictions
15do apply in other respects; for example, they cover modification of
16the file, and distribution when not linked into a combine
17executable.)
18
19GCC is distributed in the hope that it will be useful, but WITHOUT ANY
20WARRANTY; without even the implied warranty of MERCHANTABILITY or
21FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22for more details.
23
24You should have received a copy of the GNU General Public License
25along with GCC; see the file COPYING. If not, write to the Free
26Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2702110-1301, USA. */
28
29#define BID_128RES
30#include "bid_internal.h"
31
32/*****************************************************************************
33 * BID128 nextup
34 ****************************************************************************/
35
36#if DECIMAL_CALL_BY_REFERENCE
37void
38__bid128_nextup (UINT128 * pres,
39 UINT128 *
40 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
41 UINT128 x = *px;
42#else
43UINT128
44__bid128_nextup (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
45 _EXC_INFO_PARAM) {
46#endif
47
48 UINT128 res;
49 UINT64 x_sign;
50 UINT64 x_exp;
51 int exp;
52 BID_UI64DOUBLE tmp1;
53 int x_nr_bits;
54 int q1, ind;
55 UINT128 C1; // C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
56
57 BID_SWAP128(x);
58 // unpack the argument
59 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
60 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
61 C1.w[1] = x.w[1] & MASK_COEFF;
62 C1.w[0] = x.w[0];
63
64 // check for NaN or Infinity
65 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
66 // x is special
67 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
68 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
69 // set invalid flag
70 *pfpsf |= INVALID_EXCEPTION;
71 // return quiet (x)
72 res.w[1] = x.w[1] & 0xfdffffffffffffffull;
73 res.w[0] = x.w[0];
74 } else { // x is QNaN
75 // return x
76 res.w[1] = x.w[1];
77 res.w[0] = x.w[0];
78 }
79 } else { // x is not NaN, so it must be infinity
80 if (!x_sign) { // x is +inf
81 res.w[1] = 0x7800000000000000ull; // +inf
82 res.w[0] = 0x0000000000000000ull;
83 } else { // x is -inf
84 res.w[1] = 0xdfffed09bead87c0ull; // -MAXFP = -999...99 * 10^emax
85 res.w[0] = 0x378d8e63ffffffffull;
86 }
87 }
88 BID_RETURN (res);
89 }
90 // test for non-canonical values of the argument x
91 // - values whose encoding begins with x00, x01, or x10 and whose
92 // coefficient is larger than 10^34 -1, or
93 // - values whose encoding begins with x1100, x1101, x1110 (if NaNs
94 // and infinitis were eliminated already this test is reduced to
95 // checking for x10x)
96 if ((((C1.w[1] > 0x0001ed09bead87c0ull) ||
97 ((C1.w[1] == 0x0001ed09bead87c0ull) && (C1.w[0] > 0x378d8e63ffffffffull)))
98 && ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
99 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
100 x.w[1] = 0;
101 x.w[0] = 0;
102 C1.w[1] = 0;
103 C1.w[0] = 0;
104 }
105
106 if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
107 // x is +/-0
108 res.w[1] = 0x0000000000000000ull; // +1 * 10^emin
109 res.w[0] = 0x0000000000000001ull;
110 } else { // x is not special and is not zero
111 if (x.w[1] == 0x5fffed09bead87c0ull
112 && x.w[0] == 0x378d8e63ffffffffull) {
113 // x = +MAXFP = 999...99 * 10^emax
114 res.w[1] = 0x7800000000000000ull; // +inf
115 res.w[0] = 0x0000000000000000ull;
116 } else if (x.w[1] == 0x8000000000000000ull
117 && x.w[0] == 0x0000000000000001ull) {
118 // x = -MINFP = 1...99 * 10^emin
119 res.w[1] = 0x8000000000000000ull; // -0
120 res.w[0] = 0x0000000000000000ull;
121 } else { // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
122 // can add/subtract 1 ulp to the significand
123
124 // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
125 // q1 = nr. of decimal digits in x
126 // determine first the nr. of bits in x
127 if (C1.w[1] == 0) {
128 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
129 // split the 64-bit value in two 32-bit halves to avoid rnd errors
130 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
131 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
132 x_nr_bits =
133 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
134 0x3ff);
135 } else { // x < 2^32
136 tmp1.d = (double) (C1.w[0]); // exact conversion
137 x_nr_bits =
138 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
139 }
140 } else { // if x < 2^53
141 tmp1.d = (double) C1.w[0]; // exact conversion
142 x_nr_bits =
143 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
144 }
145 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
146 tmp1.d = (double) C1.w[1]; // exact conversion
147 x_nr_bits =
148 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
149 }
150 q1 = __bid_nr_digits[x_nr_bits - 1].digits;
151 if (q1 == 0) {
152 q1 = __bid_nr_digits[x_nr_bits - 1].digits1;
153 if (C1.w[1] > __bid_nr_digits[x_nr_bits - 1].threshold_hi
154 || (C1.w[1] == __bid_nr_digits[x_nr_bits - 1].threshold_hi
155 && C1.w[0] >= __bid_nr_digits[x_nr_bits - 1].threshold_lo))
156 q1++;
157 }
158 // if q1 < P34 then pad the significand with zeros
159 if (q1 < P34) {
160 exp = (x_exp >> 49) - 6176;
161 if (exp + 6176 > P34 - q1) {
162 ind = P34 - q1; // 1 <= ind <= P34 - 1
163 // pad with P34 - q1 zeros, until exponent = emin
164 // C1 = C1 * 10^ind
165 if (q1 <= 19) { // 64-bit C1
166 if (ind <= 19) { // 64-bit 10^ind and 64-bit C1
167 __mul_64x64_to_128MACH (C1, C1.w[0], __bid_ten2k64[ind]);
168 } else { // 128-bit 10^ind and 64-bit C1
169 __mul_128x64_to_128 (C1, C1.w[0], __bid_ten2k128[ind - 20]);
170 }
171 } else { // C1 is (most likely) 128-bit
172 if (ind <= 14) { // 64-bit 10^ind and 128-bit C1 (most likely)
173 __mul_128x64_to_128 (C1, __bid_ten2k64[ind], C1);
174 } else if (ind <= 19) { // 64-bit 10^ind and 64-bit C1 (q1 <= 19)
175 __mul_64x64_to_128MACH (C1, C1.w[0], __bid_ten2k64[ind]);
176 } else { // 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
177 __mul_128x64_to_128 (C1, C1.w[0], __bid_ten2k128[ind - 20]);
178 }
179 }
180 x_exp = x_exp - ((UINT64) ind << 49);
181 } else { // pad with zeros until the exponent reaches emin
182 ind = exp + 6176;
183 // C1 = C1 * 10^ind
184 if (ind <= 19) { // 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
185 if (q1 <= 19) { // 64-bit C1, 64-bit 10^ind
186 __mul_64x64_to_128MACH (C1, C1.w[0], __bid_ten2k64[ind]);
187 } else { // 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
188 __mul_128x64_to_128 (C1, __bid_ten2k64[ind], C1);
189 }
190 } else { // if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
191 // 64-bit C1, 128-bit 10^ind
192 __mul_128x64_to_128 (C1, C1.w[0], __bid_ten2k128[ind - 20]);
193 }
194 x_exp = EXP_MIN;
195 }
196 }
197 if (!x_sign) { // x > 0
198 // add 1 ulp (add 1 to the significand)
199 C1.w[0]++;
200 if (C1.w[0] == 0)
201 C1.w[1]++;
202 if (C1.w[1] == 0x0001ed09bead87c0ull &&
203 C1.w[0] == 0x378d8e6400000000ull) { // if C1 = 10^34
204 C1.w[1] = 0x0000314dc6448d93ull; // C1 = 10^33
205 C1.w[0] = 0x38c15b0a00000000ull;
206 x_exp = x_exp + EXP_P1;
207 }
208 } else { // x < 0
209 // subtract 1 ulp (subtract 1 from the significand)
210 C1.w[0]--;
211 if (C1.w[0] == 0xffffffffffffffffull)
212 C1.w[1]--;
213 if (x_exp != 0 && C1.w[1] == 0x0000314dc6448d93ull &&
214 C1.w[0] == 0x38c15b09ffffffffull) { // if C1 = 10^33 - 1
215 C1.w[1] = 0x0001ed09bead87c0ull; // C1 = 10^34 - 1
216 C1.w[0] = 0x378d8e63ffffffffull;
217 x_exp = x_exp - EXP_P1;
218 }
219 }
220 // assemble the result
221 res.w[1] = x_sign | x_exp | C1.w[1];
222 res.w[0] = C1.w[0];
223 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
224 } // end x is not special and is not zero
225 BID_RETURN (res);
226}
227
228/*****************************************************************************
229 * BID128 nextdown
230 ****************************************************************************/
231
232#if DECIMAL_CALL_BY_REFERENCE
233void
234__bid128_nextdown (UINT128 * pres,
235 UINT128 *
236 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
237 UINT128 x = *px;
238#else
239UINT128
240__bid128_nextdown (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
241 _EXC_INFO_PARAM) {
242#endif
243
244 UINT128 res;
245 UINT64 x_sign;
246 UINT64 x_exp;
247 int exp;
248 BID_UI64DOUBLE tmp1;
249 int x_nr_bits;
250 int q1, ind;
251 UINT128 C1; // C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
252
253 BID_SWAP128(x);
254 // unpack the argument
255 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
256 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions
257 C1.w[1] = x.w[1] & MASK_COEFF;
258 C1.w[0] = x.w[0];
259
260 // check for NaN or Infinity
261 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
262 // x is special
263 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
264 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
265 // set invalid flag
266 *pfpsf |= INVALID_EXCEPTION;
267 // return quiet (x)
268 res.w[1] = x.w[1] & 0xfdffffffffffffffull;
269 res.w[0] = x.w[0];
270 } else { // x is QNaN
271 // return x
272 res.w[1] = x.w[1];
273 res.w[0] = x.w[0];
274 }
275 } else { // x is not NaN, so it must be infinity
276 if (!x_sign) { // x is +inf
277 res.w[1] = 0x5fffed09bead87c0ull; // +MAXFP = +999...99 * 10^emax
278 res.w[0] = 0x378d8e63ffffffffull;
279 } else { // x is -inf
280 res.w[1] = 0xf800000000000000ull; // -inf
281 res.w[0] = 0x0000000000000000ull;
282 }
283 }
284 BID_RETURN (res);
285 }
286 // test for non-canonical values of the argument x
287 // - values whose encoding begins with x00, x01, or x10 and whose
288 // coefficient is larger than 10^34 -1, or
289 // - values whose encoding begins with x1100, x1101, x1110 (if NaNs
290 // and infinitis were eliminated already this test is reduced to
291 // checking for x10x)
292 if ((((C1.w[1] > 0x0001ed09bead87c0ull) || ((C1.w[1] == 0x0001ed09bead87c0ull)
293 && (C1.w[0] > 0x378d8e63ffffffffull))) &&
294 ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) ||
295 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
296 x.w[1] = 0;
297 x.w[0] = 0;
298 C1.w[1] = 0;
299 C1.w[0] = 0;
300 }
301
302 if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
303 // x is +/-0
304 res.w[1] = 0x8000000000000000ull; // -1 * 10^emin
305 res.w[0] = 0x0000000000000001ull;
306 } else { // x is not special and is not zero
307 if (x.w[1] == 0xdfffed09bead87c0ull
308 && x.w[0] == 0x378d8e63ffffffffull) {
309 // x = -MAXFP = -999...99 * 10^emax
310 res.w[1] = 0xf800000000000000ull; // -inf
311 res.w[0] = 0x0000000000000000ull;
312 } else if (x.w[1] == 0x0ull && x.w[0] == 0x0000000000000001ull) { // +MINFP
313 res.w[1] = 0x0000000000000000ull; // +0
314 res.w[0] = 0x0000000000000000ull;
315 } else { // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
316 // can add/subtract 1 ulp to the significand
317
318 // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
319 // q1 = nr. of decimal digits in x
320 // determine first the nr. of bits in x
321 if (C1.w[1] == 0) {
322 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
323 // split the 64-bit value in two 32-bit halves to avoid rnd errors
324 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
325 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
326 x_nr_bits =
327 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
328 0x3ff);
329 } else { // x < 2^32
330 tmp1.d = (double) (C1.w[0]); // exact conversion
331 x_nr_bits =
332 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
333 }
334 } else { // if x < 2^53
335 tmp1.d = (double) C1.w[0]; // exact conversion
336 x_nr_bits =
337 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
338 }
339 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
340 tmp1.d = (double) C1.w[1]; // exact conversion
341 x_nr_bits =
342 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
343 }
344 q1 = __bid_nr_digits[x_nr_bits - 1].digits;
345 if (q1 == 0) {
346 q1 = __bid_nr_digits[x_nr_bits - 1].digits1;
347 if (C1.w[1] > __bid_nr_digits[x_nr_bits - 1].threshold_hi
348 || (C1.w[1] == __bid_nr_digits[x_nr_bits - 1].threshold_hi
349 && C1.w[0] >= __bid_nr_digits[x_nr_bits - 1].threshold_lo))
350 q1++;
351 }
352 // if q1 < P then pad the significand with zeros
353 if (q1 < P34) {
354 exp = (x_exp >> 49) - 6176;
355 if (exp + 6176 > P34 - q1) {
356 ind = P34 - q1; // 1 <= ind <= P34 - 1
357 // pad with P34 - q1 zeros, until exponent = emin
358 // C1 = C1 * 10^ind
359 if (q1 <= 19) { // 64-bit C1
360 if (ind <= 19) { // 64-bit 10^ind and 64-bit C1
361 __mul_64x64_to_128MACH (C1, C1.w[0], __bid_ten2k64[ind]);
362 } else { // 128-bit 10^ind and 64-bit C1
363 __mul_128x64_to_128 (C1, C1.w[0], __bid_ten2k128[ind - 20]);
364 }
365 } else { // C1 is (most likely) 128-bit
366 if (ind <= 14) { // 64-bit 10^ind and 128-bit C1 (most likely)
367 __mul_128x64_to_128 (C1, __bid_ten2k64[ind], C1);
368 } else if (ind <= 19) { // 64-bit 10^ind and 64-bit C1 (q1 <= 19)
369 __mul_64x64_to_128MACH (C1, C1.w[0], __bid_ten2k64[ind]);
370 } else { // 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
371 __mul_128x64_to_128 (C1, C1.w[0], __bid_ten2k128[ind - 20]);
372 }
373 }
374 x_exp = x_exp - ((UINT64) ind << 49);
375 } else { // pad with zeros until the exponent reaches emin
376 ind = exp + 6176;
377 // C1 = C1 * 10^ind
378 if (ind <= 19) { // 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
379 if (q1 <= 19) { // 64-bit C1, 64-bit 10^ind
380 __mul_64x64_to_128MACH (C1, C1.w[0], __bid_ten2k64[ind]);
381 } else { // 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
382 __mul_128x64_to_128 (C1, __bid_ten2k64[ind], C1);
383 }
384 } else { // if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
385 // 64-bit C1, 128-bit 10^ind
386 __mul_128x64_to_128 (C1, C1.w[0], __bid_ten2k128[ind - 20]);
387 }
388 x_exp = EXP_MIN;
389 }
390 }
391 if (x_sign) { // x < 0
392 // add 1 ulp (add 1 to the significand)
393 C1.w[0]++;
394 if (C1.w[0] == 0)
395 C1.w[1]++;
396 if (C1.w[1] == 0x0001ed09bead87c0ull &&
397 C1.w[0] == 0x378d8e6400000000ull) { // if C1 = 10^34
398 C1.w[1] = 0x0000314dc6448d93ull; // C1 = 10^33
399 C1.w[0] = 0x38c15b0a00000000ull;
400 x_exp = x_exp + EXP_P1;
401 }
402 } else { // x > 0
403 // subtract 1 ulp (subtract 1 from the significand)
404 C1.w[0]--;
405 if (C1.w[0] == 0xffffffffffffffffull)
406 C1.w[1]--;
407 if (x_exp != 0 && C1.w[1] == 0x0000314dc6448d93ull &&
408 C1.w[0] == 0x38c15b09ffffffffull) { // if C1 = 10^33 - 1
409 C1.w[1] = 0x0001ed09bead87c0ull; // C1 = 10^34 - 1
410 C1.w[0] = 0x378d8e63ffffffffull;
411 x_exp = x_exp - EXP_P1;
412 }
413 }
414 // assemble the result
415 res.w[1] = x_sign | x_exp | C1.w[1];
416 res.w[0] = C1.w[0];
417 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
418 } // end x is not special and is not zero
419 BID_RETURN (res);
420}
421
422/*****************************************************************************
423 * BID128 nextafter
424 ****************************************************************************/
425
426#if DECIMAL_CALL_BY_REFERENCE
427void
428__bid128_nextafter (UINT128 * pres, UINT128 * px,
429 UINT128 *
430 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
431{
432 UINT128 x = *px;
433 UINT128 y = *py;
434 UINT128 xnswp = *px;
435 UINT128 ynswp = *py;
436#else
437UINT128
438__bid128_nextafter (UINT128 x,
439 UINT128 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
440 _EXC_INFO_PARAM) {
441 UINT128 xnswp = x;
442 UINT128 ynswp = y;
443#endif
444
445 UINT128 res;
446 UINT128 tmp1, tmp2;
447 FPSC tmp_fpsf = 0; // dummy fpsf for calls to comparison functions
448 int res1, res2;
449
450 BID_SWAP128(x);
451 BID_SWAP128(y);
452 // check for NaNs
453 if (((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL)
454 || ((y.w[1] & MASK_SPECIAL) == MASK_SPECIAL)) {
455 // x is special or y is special
456
457 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
458 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
459 // set invalid flag
460 *pfpsf |= INVALID_EXCEPTION;
461 // return quiet (x)
462 res.w[1] = x.w[1] & 0xfdffffffffffffffull;
463 res.w[0] = x.w[0];
464 } else { // x is QNaN
465 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
466 // set invalid flag
467 *pfpsf |= INVALID_EXCEPTION;
468 }
469 // return x
470 res.w[1] = x.w[1];
471 res.w[0] = x.w[0];
472 }
473 BID_RETURN (res);
474 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
475 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
476 // set invalid flag
477 *pfpsf |= INVALID_EXCEPTION;
478 // return quiet (y)
479 res.w[1] = y.w[1] & 0xfdffffffffffffffull;
480 res.w[0] = y.w[0];
481 } else { // y is QNaN
482 // return y
483 res.w[1] = y.w[1];
484 res.w[0] = y.w[0];
485 }
486 BID_RETURN (res);
487 } else {
488 ; // let infinities fall through
489 }
490 }
491 // neither x nor y is NaN
492 tmp_fpsf = *pfpsf; // save fpsf
493#if DECIMAL_CALL_BY_REFERENCE
494 __bid128_quiet_equal (&res1, &xnswp,
495 &ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
496 __bid128_quiet_greater (&res2, &xnswp,
497 &ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
498#else
499 res1 =
500 __bid128_quiet_equal (xnswp,
501 ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
502 res2 =
503 __bid128_quiet_greater (xnswp,
504 ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
505 _EXC_INFO_ARG);
506#endif
507 *pfpsf = tmp_fpsf; // restore fpsf
508 if (res1) { // x = y
509 // return x with the sign of y
510 res.w[1] =
511 (x.w[1] & 0x7fffffffffffffffull) | (y.w[1] & 0x8000000000000000ull);
512 res.w[0] = x.w[0];
513 } else if (res2) { // x > y
514#if DECIMAL_CALL_BY_REFERENCE
515 __bid128_nextdown (&res,
516 &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
517#else
518 res =
519 __bid128_nextdown (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
520#endif
521 BID_SWAP128(res);
522 } else { // x < y
523#if DECIMAL_CALL_BY_REFERENCE
524 __bid128_nextup (&res,
525 &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
526#else
527 res = __bid128_nextup (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
528#endif
529 BID_SWAP128(res);
530 }
531 // if the operand x is finite but the result is infinite, signal
532 // overflow and inexact
533 if (((x.w[1] & MASK_SPECIAL) != MASK_SPECIAL)
534 && ((res.w[1] & MASK_SPECIAL) == MASK_SPECIAL)) {
535 // set the inexact flag
536 *pfpsf |= INEXACT_EXCEPTION;
537 // set the overflow flag
538 *pfpsf |= OVERFLOW_EXCEPTION;
539 }
540 // if the result is in (-10^emin, 10^emin), and is different from the
541 // operand x, signal underflow and inexact
542 tmp1.w[HIGH_128W] = 0x0000314dc6448d93ull;
543 tmp1.w[LOW_128W] = 0x38c15b0a00000000ull; // +100...0[34] * 10^emin
544 tmp2.w[HIGH_128W] = res.w[1] & 0x7fffffffffffffffull;
545 tmp2.w[LOW_128W] = res.w[0];
546 tmp_fpsf = *pfpsf; // save fpsf
547#if DECIMAL_CALL_BY_REFERENCE
548 __bid128_quiet_greater (&res1, &tmp1,
549 &tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
550 _EXC_INFO_ARG);
551 __bid128_quiet_not_equal (&res2, &xnswp,
552 &res _EXC_FLAGS_ARG _EXC_MASKS_ARG
553 _EXC_INFO_ARG);
554#else
555 res1 =
556 __bid128_quiet_greater (tmp1,
557 tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
558 _EXC_INFO_ARG);
559 res2 =
560 __bid128_quiet_not_equal (xnswp,
561 res _EXC_FLAGS_ARG _EXC_MASKS_ARG
562 _EXC_INFO_ARG);
563#endif
564 *pfpsf = tmp_fpsf; // restore fpsf
565 if (res1 && res2) {
566 // set the inexact flag
567 *pfpsf |= INEXACT_EXCEPTION;
568 // set the underflow flag
569 *pfpsf |= UNDERFLOW_EXCEPTION;
570 }
571 BID_RETURN (res);
572}