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