1 /* Copyright (C) 2007-2019 Free Software Foundation, Inc.
2
3 This file is part of GCC.
4
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
8 version.
9
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
13 for more details.
14
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.
18
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/>. */
23
24 #define BID_128RES
25 #include "bid_internal.h"
26
27 /*****************************************************************************
28 * BID128 nextup
29 ****************************************************************************/
30
31 #if DECIMAL_CALL_BY_REFERENCE
32 void
bid128_nextup(UINT128 * pres,UINT128 * px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)33 bid128_nextup (UINT128 * pres,
34 UINT128 *
35 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
36 UINT128 x = *px;
37 #else
38 UINT128
39 bid128_nextup (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
40 _EXC_INFO_PARAM) {
41 #endif
42
43 UINT128 res;
44 UINT64 x_sign;
45 UINT64 x_exp;
46 int exp;
47 BID_UI64DOUBLE tmp1;
48 int x_nr_bits;
49 int q1, ind;
50 UINT128 C1; // C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
51
52 BID_SWAP128 (x);
53 // unpack the argument
54 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
55 C1.w[1] = x.w[1] & MASK_COEFF;
56 C1.w[0] = x.w[0];
57
58 // check for NaN or Infinity
59 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
60 // x is special
61 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
62 // if x = NaN, then res = Q (x)
63 // check first for non-canonical NaN payload
64 if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
65 (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
66 && (x.w[0] > 0x38c15b09ffffffffull))) {
67 x.w[1] = x.w[1] & 0xffffc00000000000ull;
68 x.w[0] = 0x0ull;
69 }
70 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
71 // set invalid flag
72 *pfpsf |= INVALID_EXCEPTION;
73 // return quiet (x)
74 res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
75 res.w[0] = x.w[0];
76 } else { // x is QNaN
77 // return x
78 res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
79 res.w[0] = x.w[0];
80 }
81 } else { // x is not NaN, so it must be infinity
82 if (!x_sign) { // x is +inf
83 res.w[1] = 0x7800000000000000ull; // +inf
84 res.w[0] = 0x0000000000000000ull;
85 } else { // x is -inf
86 res.w[1] = 0xdfffed09bead87c0ull; // -MAXFP = -999...99 * 10^emax
87 res.w[0] = 0x378d8e63ffffffffull;
88 }
89 }
90 BID_RETURN (res);
91 }
92 // check for non-canonical values (treated as zero)
93 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
94 // non-canonical
95 x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
96 C1.w[1] = 0; // significand high
97 C1.w[0] = 0; // significand low
98 } else { // G0_G1 != 11
99 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
100 if (C1.w[1] > 0x0001ed09bead87c0ull ||
101 (C1.w[1] == 0x0001ed09bead87c0ull
102 && C1.w[0] > 0x378d8e63ffffffffull)) {
103 // x is non-canonical if coefficient is larger than 10^34 -1
104 C1.w[1] = 0;
105 C1.w[0] = 0;
106 } else { // canonical
107 ;
108 }
109 }
110
111 if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
112 // x is +/-0
113 res.w[1] = 0x0000000000000000ull; // +1 * 10^emin
114 res.w[0] = 0x0000000000000001ull;
115 } else { // x is not special and is not zero
116 if (x.w[1] == 0x5fffed09bead87c0ull
117 && x.w[0] == 0x378d8e63ffffffffull) {
118 // x = +MAXFP = 999...99 * 10^emax
119 res.w[1] = 0x7800000000000000ull; // +inf
120 res.w[0] = 0x0000000000000000ull;
121 } else if (x.w[1] == 0x8000000000000000ull
122 && x.w[0] == 0x0000000000000001ull) {
123 // x = -MINFP = 1...99 * 10^emin
124 res.w[1] = 0x8000000000000000ull; // -0
125 res.w[0] = 0x0000000000000000ull;
126 } else { // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
127 // can add/subtract 1 ulp to the significand
128
129 // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
130 // q1 = nr. of decimal digits in x
131 // determine first the nr. of bits in x
132 if (C1.w[1] == 0) {
133 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
134 // split the 64-bit value in two 32-bit halves to avoid rnd errors
135 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
136 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
137 x_nr_bits =
138 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
139 0x3ff);
140 } else { // x < 2^32
141 tmp1.d = (double) (C1.w[0]); // exact conversion
142 x_nr_bits =
143 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
144 0x3ff);
145 }
146 } else { // if x < 2^53
147 tmp1.d = (double) C1.w[0]; // exact conversion
148 x_nr_bits =
149 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
150 }
151 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
152 tmp1.d = (double) C1.w[1]; // exact conversion
153 x_nr_bits =
154 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
155 }
156 q1 = nr_digits[x_nr_bits - 1].digits;
157 if (q1 == 0) {
158 q1 = nr_digits[x_nr_bits - 1].digits1;
159 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
160 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
161 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
162 q1++;
163 }
164 // if q1 < P34 then pad the significand with zeros
165 if (q1 < P34) {
166 exp = (x_exp >> 49) - 6176;
167 if (exp + 6176 > P34 - q1) {
168 ind = P34 - q1; // 1 <= ind <= P34 - 1
169 // pad with P34 - q1 zeros, until exponent = emin
170 // C1 = C1 * 10^ind
171 if (q1 <= 19) { // 64-bit C1
172 if (ind <= 19) { // 64-bit 10^ind and 64-bit C1
173 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
174 } else { // 128-bit 10^ind and 64-bit C1
175 __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
176 }
177 } else { // C1 is (most likely) 128-bit
178 if (ind <= 14) { // 64-bit 10^ind and 128-bit C1 (most likely)
179 __mul_128x64_to_128 (C1, ten2k64[ind], C1);
180 } else if (ind <= 19) { // 64-bit 10^ind and 64-bit C1 (q1 <= 19)
181 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
182 } else { // 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
183 __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
184 }
185 }
186 x_exp = x_exp - ((UINT64) ind << 49);
187 } else { // pad with zeros until the exponent reaches emin
188 ind = exp + 6176;
189 // C1 = C1 * 10^ind
190 if (ind <= 19) { // 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
191 if (q1 <= 19) { // 64-bit C1, 64-bit 10^ind
192 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
193 } else { // 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
194 __mul_128x64_to_128 (C1, ten2k64[ind], C1);
195 }
196 } else { // if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
197 // 64-bit C1, 128-bit 10^ind
198 __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
199 }
200 x_exp = EXP_MIN;
201 }
202 }
203 if (!x_sign) { // x > 0
204 // add 1 ulp (add 1 to the significand)
205 C1.w[0]++;
206 if (C1.w[0] == 0)
207 C1.w[1]++;
208 if (C1.w[1] == 0x0001ed09bead87c0ull && C1.w[0] == 0x378d8e6400000000ull) { // if C1 = 10^34
209 C1.w[1] = 0x0000314dc6448d93ull; // C1 = 10^33
210 C1.w[0] = 0x38c15b0a00000000ull;
211 x_exp = x_exp + EXP_P1;
212 }
213 } else { // x < 0
214 // subtract 1 ulp (subtract 1 from the significand)
215 C1.w[0]--;
216 if (C1.w[0] == 0xffffffffffffffffull)
217 C1.w[1]--;
218 if (x_exp != 0 && C1.w[1] == 0x0000314dc6448d93ull && C1.w[0] == 0x38c15b09ffffffffull) { // if C1 = 10^33 - 1
219 C1.w[1] = 0x0001ed09bead87c0ull; // C1 = 10^34 - 1
220 C1.w[0] = 0x378d8e63ffffffffull;
221 x_exp = x_exp - EXP_P1;
222 }
223 }
224 // assemble the result
225 res.w[1] = x_sign | x_exp | C1.w[1];
226 res.w[0] = C1.w[0];
227 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
228 } // end x is not special and is not zero
229 BID_RETURN (res);
230 }
231
232 /*****************************************************************************
233 * BID128 nextdown
234 ****************************************************************************/
235
236 #if DECIMAL_CALL_BY_REFERENCE
237 void
238 bid128_nextdown (UINT128 * pres,
239 UINT128 *
240 px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
241 UINT128 x = *px;
242 #else
243 UINT128
244 bid128_nextdown (UINT128 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
245 _EXC_INFO_PARAM) {
246 #endif
247
248 UINT128 res;
249 UINT64 x_sign;
250 UINT64 x_exp;
251 int exp;
252 BID_UI64DOUBLE tmp1;
253 int x_nr_bits;
254 int q1, ind;
255 UINT128 C1; // C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (UINT64)
256
257 BID_SWAP128 (x);
258 // unpack the argument
259 x_sign = x.w[1] & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
260 C1.w[1] = x.w[1] & MASK_COEFF;
261 C1.w[0] = x.w[0];
262
263 // check for NaN or Infinity
264 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
265 // x is special
266 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
267 // if x = NaN, then res = Q (x)
268 // check first for non-canonical NaN payload
269 if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
270 (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
271 && (x.w[0] > 0x38c15b09ffffffffull))) {
272 x.w[1] = x.w[1] & 0xffffc00000000000ull;
273 x.w[0] = 0x0ull;
274 }
275 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
276 // set invalid flag
277 *pfpsf |= INVALID_EXCEPTION;
278 // return quiet (x)
279 res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
280 res.w[0] = x.w[0];
281 } else { // x is QNaN
282 // return x
283 res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
284 res.w[0] = x.w[0];
285 }
286 } else { // x is not NaN, so it must be infinity
287 if (!x_sign) { // x is +inf
288 res.w[1] = 0x5fffed09bead87c0ull; // +MAXFP = +999...99 * 10^emax
289 res.w[0] = 0x378d8e63ffffffffull;
290 } else { // x is -inf
291 res.w[1] = 0xf800000000000000ull; // -inf
292 res.w[0] = 0x0000000000000000ull;
293 }
294 }
295 BID_RETURN (res);
296 }
297 // check for non-canonical values (treated as zero)
298 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
299 // non-canonical
300 x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
301 C1.w[1] = 0; // significand high
302 C1.w[0] = 0; // significand low
303 } else { // G0_G1 != 11
304 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
305 if (C1.w[1] > 0x0001ed09bead87c0ull ||
306 (C1.w[1] == 0x0001ed09bead87c0ull
307 && C1.w[0] > 0x378d8e63ffffffffull)) {
308 // x is non-canonical if coefficient is larger than 10^34 -1
309 C1.w[1] = 0;
310 C1.w[0] = 0;
311 } else { // canonical
312 ;
313 }
314 }
315
316 if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
317 // x is +/-0
318 res.w[1] = 0x8000000000000000ull; // -1 * 10^emin
319 res.w[0] = 0x0000000000000001ull;
320 } else { // x is not special and is not zero
321 if (x.w[1] == 0xdfffed09bead87c0ull
322 && x.w[0] == 0x378d8e63ffffffffull) {
323 // x = -MAXFP = -999...99 * 10^emax
324 res.w[1] = 0xf800000000000000ull; // -inf
325 res.w[0] = 0x0000000000000000ull;
326 } else if (x.w[1] == 0x0ull && x.w[0] == 0x0000000000000001ull) { // +MINFP
327 res.w[1] = 0x0000000000000000ull; // +0
328 res.w[0] = 0x0000000000000000ull;
329 } else { // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
330 // can add/subtract 1 ulp to the significand
331
332 // Note: we could check here if x >= 10^34 to speed up the case q1 = 34
333 // q1 = nr. of decimal digits in x
334 // determine first the nr. of bits in x
335 if (C1.w[1] == 0) {
336 if (C1.w[0] >= 0x0020000000000000ull) { // x >= 2^53
337 // split the 64-bit value in two 32-bit halves to avoid rnd errors
338 if (C1.w[0] >= 0x0000000100000000ull) { // x >= 2^32
339 tmp1.d = (double) (C1.w[0] >> 32); // exact conversion
340 x_nr_bits =
341 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
342 0x3ff);
343 } else { // x < 2^32
344 tmp1.d = (double) (C1.w[0]); // exact conversion
345 x_nr_bits =
346 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
347 0x3ff);
348 }
349 } else { // if x < 2^53
350 tmp1.d = (double) C1.w[0]; // exact conversion
351 x_nr_bits =
352 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
353 }
354 } else { // C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
355 tmp1.d = (double) C1.w[1]; // exact conversion
356 x_nr_bits =
357 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
358 }
359 q1 = nr_digits[x_nr_bits - 1].digits;
360 if (q1 == 0) {
361 q1 = nr_digits[x_nr_bits - 1].digits1;
362 if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
363 || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
364 && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
365 q1++;
366 }
367 // if q1 < P then pad the significand with zeros
368 if (q1 < P34) {
369 exp = (x_exp >> 49) - 6176;
370 if (exp + 6176 > P34 - q1) {
371 ind = P34 - q1; // 1 <= ind <= P34 - 1
372 // pad with P34 - q1 zeros, until exponent = emin
373 // C1 = C1 * 10^ind
374 if (q1 <= 19) { // 64-bit C1
375 if (ind <= 19) { // 64-bit 10^ind and 64-bit C1
376 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
377 } else { // 128-bit 10^ind and 64-bit C1
378 __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
379 }
380 } else { // C1 is (most likely) 128-bit
381 if (ind <= 14) { // 64-bit 10^ind and 128-bit C1 (most likely)
382 __mul_128x64_to_128 (C1, ten2k64[ind], C1);
383 } else if (ind <= 19) { // 64-bit 10^ind and 64-bit C1 (q1 <= 19)
384 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
385 } else { // 128-bit 10^ind and 64-bit C1 (C1 must be 64-bit)
386 __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
387 }
388 }
389 x_exp = x_exp - ((UINT64) ind << 49);
390 } else { // pad with zeros until the exponent reaches emin
391 ind = exp + 6176;
392 // C1 = C1 * 10^ind
393 if (ind <= 19) { // 1 <= P34 - q1 <= 19 <=> 15 <= q1 <= 33
394 if (q1 <= 19) { // 64-bit C1, 64-bit 10^ind
395 __mul_64x64_to_128MACH (C1, C1.w[0], ten2k64[ind]);
396 } else { // 20 <= q1 <= 33 => 128-bit C1, 64-bit 10^ind
397 __mul_128x64_to_128 (C1, ten2k64[ind], C1);
398 }
399 } else { // if 20 <= P34 - q1 <= 33 <=> 1 <= q1 <= 14 =>
400 // 64-bit C1, 128-bit 10^ind
401 __mul_128x64_to_128 (C1, C1.w[0], ten2k128[ind - 20]);
402 }
403 x_exp = EXP_MIN;
404 }
405 }
406 if (x_sign) { // x < 0
407 // add 1 ulp (add 1 to the significand)
408 C1.w[0]++;
409 if (C1.w[0] == 0)
410 C1.w[1]++;
411 if (C1.w[1] == 0x0001ed09bead87c0ull && C1.w[0] == 0x378d8e6400000000ull) { // if C1 = 10^34
412 C1.w[1] = 0x0000314dc6448d93ull; // C1 = 10^33
413 C1.w[0] = 0x38c15b0a00000000ull;
414 x_exp = x_exp + EXP_P1;
415 }
416 } else { // x > 0
417 // subtract 1 ulp (subtract 1 from the significand)
418 C1.w[0]--;
419 if (C1.w[0] == 0xffffffffffffffffull)
420 C1.w[1]--;
421 if (x_exp != 0 && C1.w[1] == 0x0000314dc6448d93ull && C1.w[0] == 0x38c15b09ffffffffull) { // if C1 = 10^33 - 1
422 C1.w[1] = 0x0001ed09bead87c0ull; // C1 = 10^34 - 1
423 C1.w[0] = 0x378d8e63ffffffffull;
424 x_exp = x_exp - EXP_P1;
425 }
426 }
427 // assemble the result
428 res.w[1] = x_sign | x_exp | C1.w[1];
429 res.w[0] = C1.w[0];
430 } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
431 } // end x is not special and is not zero
432 BID_RETURN (res);
433 }
434
435 /*****************************************************************************
436 * BID128 nextafter
437 ****************************************************************************/
438
439 #if DECIMAL_CALL_BY_REFERENCE
440 void
441 bid128_nextafter (UINT128 * pres, UINT128 * px,
442 UINT128 *
443 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)
444 {
445 UINT128 x = *px;
446 UINT128 y = *py;
447 UINT128 xnswp = *px;
448 UINT128 ynswp = *py;
449 #else
450 UINT128
451 bid128_nextafter (UINT128 x,
452 UINT128 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
453 _EXC_INFO_PARAM) {
454 UINT128 xnswp = x;
455 UINT128 ynswp = y;
456 #endif
457
458 UINT128 res;
459 UINT128 tmp1, tmp2, tmp3;
460 FPSC tmp_fpsf = 0; // dummy fpsf for calls to comparison functions
461 int res1, res2;
462 UINT64 x_exp;
463
464
465 BID_SWAP128 (x);
466 BID_SWAP128 (y);
467 // check for NaNs
468 if (((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL)
469 || ((y.w[1] & MASK_SPECIAL) == MASK_SPECIAL)) {
470 // x is special or y is special
471 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
472 // if x = NaN, then res = Q (x)
473 // check first for non-canonical NaN payload
474 if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
475 (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
476 && (x.w[0] > 0x38c15b09ffffffffull))) {
477 x.w[1] = x.w[1] & 0xffffc00000000000ull;
478 x.w[0] = 0x0ull;
479 }
480 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
481 // set invalid flag
482 *pfpsf |= INVALID_EXCEPTION;
483 // return quiet (x)
484 res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
485 res.w[0] = x.w[0];
486 } else { // x is QNaN
487 // return x
488 res.w[1] = x.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
489 res.w[0] = x.w[0];
490 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
491 // set invalid flag
492 *pfpsf |= INVALID_EXCEPTION;
493 }
494 }
495 BID_RETURN (res)
496 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { // y is NAN
497 // if x = NaN, then res = Q (x)
498 // check first for non-canonical NaN payload
499 if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
500 (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
501 && (y.w[0] > 0x38c15b09ffffffffull))) {
502 y.w[1] = y.w[1] & 0xffffc00000000000ull;
503 y.w[0] = 0x0ull;
504 }
505 if ((y.w[1] & MASK_SNAN) == MASK_SNAN) { // y is SNAN
506 // set invalid flag
507 *pfpsf |= INVALID_EXCEPTION;
508 // return quiet (x)
509 res.w[1] = y.w[1] & 0xfc003fffffffffffull; // clear out also G[6]-G[16]
510 res.w[0] = y.w[0];
511 } else { // x is QNaN
512 // return x
513 res.w[1] = y.w[1] & 0xfc003fffffffffffull; // clear out G[6]-G[16]
514 res.w[0] = y.w[0];
515 }
516 BID_RETURN (res)
517 } else { // at least one is infinity
518 if ((x.w[1] & MASK_ANY_INF) == MASK_INF) { // x = inf
519 x.w[1] = x.w[1] & (MASK_SIGN | MASK_INF);
520 x.w[0] = 0x0ull;
521 }
522 if ((y.w[1] & MASK_ANY_INF) == MASK_INF) { // y = inf
523 y.w[1] = y.w[1] & (MASK_SIGN | MASK_INF);
524 y.w[0] = 0x0ull;
525 }
526 }
527 }
528 // neither x nor y is NaN
529
530 // if not infinity, check for non-canonical values x (treated as zero)
531 if ((x.w[1] & MASK_ANY_INF) != MASK_INF) { // x != inf
532 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11
533 // non-canonical
534 x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
535 x.w[1] = (x.w[1] & MASK_SIGN) | x_exp;
536 x.w[0] = 0x0ull;
537 } else { // G0_G1 != 11
538 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits
539 if ((x.w[1] & MASK_COEFF) > 0x0001ed09bead87c0ull ||
540 ((x.w[1] & MASK_COEFF) == 0x0001ed09bead87c0ull
541 && x.w[0] > 0x378d8e63ffffffffull)) {
542 // x is non-canonical if coefficient is larger than 10^34 -1
543 x.w[1] = (x.w[1] & MASK_SIGN) | x_exp;
544 x.w[0] = 0x0ull;
545 } else { // canonical
546 ;
547 }
548 }
549 }
550 // no need to check for non-canonical y
551
552 // neither x nor y is NaN
553 tmp_fpsf = *pfpsf; // save fpsf
554 #if DECIMAL_CALL_BY_REFERENCE
555 bid128_quiet_equal (&res1, &xnswp,
556 &ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
557 _EXC_INFO_ARG);
558 bid128_quiet_greater (&res2, &xnswp,
559 &ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
560 _EXC_INFO_ARG);
561 #else
562 res1 =
563 bid128_quiet_equal (xnswp,
564 ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
565 _EXC_INFO_ARG);
566 res2 =
567 bid128_quiet_greater (xnswp,
568 ynswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
569 _EXC_INFO_ARG);
570 #endif
571 *pfpsf = tmp_fpsf; // restore fpsf
572
573 if (res1) { // x = y
574 // return x with the sign of y
575 res.w[1] =
576 (x.w[1] & 0x7fffffffffffffffull) | (y.
577 w[1] & 0x8000000000000000ull);
578 res.w[0] = x.w[0];
579 } else if (res2) { // x > y
580 #if DECIMAL_CALL_BY_REFERENCE
581 bid128_nextdown (&res,
582 &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
583 _EXC_INFO_ARG);
584 #else
585 res =
586 bid128_nextdown (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG
587 _EXC_INFO_ARG);
588 #endif
589 BID_SWAP128 (res);
590 } else { // x < y
591 #if DECIMAL_CALL_BY_REFERENCE
592 bid128_nextup (&res,
593 &xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
594 #else
595 res =
596 bid128_nextup (xnswp _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
597 #endif
598 BID_SWAP128 (res);
599 }
600 // if the operand x is finite but the result is infinite, signal
601 // overflow and inexact
602 if (((x.w[1] & MASK_SPECIAL) != MASK_SPECIAL)
603 && ((res.w[1] & MASK_SPECIAL) == MASK_SPECIAL)) {
604 // set the inexact flag
605 *pfpsf |= INEXACT_EXCEPTION;
606 // set the overflow flag
607 *pfpsf |= OVERFLOW_EXCEPTION;
608 }
609 // if the result is in (-10^emin, 10^emin), and is different from the
610 // operand x, signal underflow and inexact
611 tmp1.w[HIGH_128W] = 0x0000314dc6448d93ull;
612 tmp1.w[LOW_128W] = 0x38c15b0a00000000ull; // +100...0[34] * 10^emin
613 tmp2.w[HIGH_128W] = res.w[1] & 0x7fffffffffffffffull;
614 tmp2.w[LOW_128W] = res.w[0];
615 tmp3.w[HIGH_128W] = res.w[1];
616 tmp3.w[LOW_128W] = res.w[0];
617 tmp_fpsf = *pfpsf; // save fpsf
618 #if DECIMAL_CALL_BY_REFERENCE
619 bid128_quiet_greater (&res1, &tmp1,
620 &tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
621 _EXC_INFO_ARG);
622 bid128_quiet_not_equal (&res2, &xnswp,
623 &tmp3 _EXC_FLAGS_ARG _EXC_MASKS_ARG
624 _EXC_INFO_ARG);
625 #else
626 res1 =
627 bid128_quiet_greater (tmp1,
628 tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
629 _EXC_INFO_ARG);
630 res2 =
631 bid128_quiet_not_equal (xnswp,
632 tmp3 _EXC_FLAGS_ARG _EXC_MASKS_ARG
633 _EXC_INFO_ARG);
634 #endif
635 *pfpsf = tmp_fpsf; // restore fpsf
636 if (res1 && res2) {
637 // set the inexact flag
638 *pfpsf |= INEXACT_EXCEPTION;
639 // set the underflow flag
640 *pfpsf |= UNDERFLOW_EXCEPTION;
641 }
642 BID_RETURN (res);
643 }
644