1 /* Copyright (C) 2007-2018 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 #include "bid_internal.h"
25 
26 /*****************************************************************************
27  *  BID64 nextup
28  ****************************************************************************/
29 
30 #if DECIMAL_CALL_BY_REFERENCE
31 void
bid64_nextup(UINT64 * pres,UINT64 * px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)32 bid64_nextup (UINT64 * pres,
33 	      UINT64 *
34 	      px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
35   UINT64 x = *px;
36 #else
37 UINT64
38 bid64_nextup (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
39 	      _EXC_INFO_PARAM) {
40 #endif
41 
42   UINT64 res;
43   UINT64 x_sign;
44   UINT64 x_exp;
45   BID_UI64DOUBLE tmp1;
46   int x_nr_bits;
47   int q1, ind;
48   UINT64 C1;			// C1 represents x_signif (UINT64)
49 
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
54     else
55       x = x & 0xfe03ffffffffffffull;	// clear G6-G12
56     if ((x & MASK_SNAN) == MASK_SNAN) {	// SNaN
57       // set invalid flag
58       *pfpsf |= INVALID_EXCEPTION;
59       // return quiet (SNaN)
60       res = x & 0xfdffffffffffffffull;
61     } else {	// QNaN
62       res = x;
63     }
64     BID_RETURN (res);
65   } else if ((x & MASK_INF) == MASK_INF) {	// check for Infinity
66     if (!(x & 0x8000000000000000ull)) {	// x is +inf
67       res = 0x7800000000000000ull;
68     } else {	// x is -inf
69       res = 0xf7fb86f26fc0ffffull;	// -MAXFP = -999...99 * 10^emax
70     }
71     BID_RETURN (res);
72   }
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
80       x_exp = 0;
81       C1 = 0;
82     }
83   } else {
84     x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
85     C1 = x & MASK_BINARY_SIG1;
86   }
87 
88   // check for zeros (possibly from non-canonical values)
89   if (C1 == 0x0ull) {
90     // x is 0
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
101 
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
109 	  x_nr_bits =
110 	    33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
111 	} else {	// x < 2^32
112 	  tmp1.d = (double) C1;	// exact conversion
113 	  x_nr_bits =
114 	    1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
115 	}
116       } else {	// if x < 2^53
117 	tmp1.d = (double) C1;	// exact conversion
118 	x_nr_bits =
119 	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
120       }
121       q1 = nr_digits[x_nr_bits - 1].digits;
122       if (q1 == 0) {
123 	q1 = nr_digits[x_nr_bits - 1].digits1;
124 	if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
125 	  q1++;
126       }
127       // if q1 < P16 then pad the significand with zeros
128       if (q1 < P16) {
129 	if (x_exp > (UINT64) (P16 - q1)) {
130 	  ind = P16 - q1;	// 1 <= ind <= P16 - 1
131 	  // pad with P16 - q1 zeros, until exponent = emin
132 	  // C1 = C1 * 10^ind
133 	  C1 = C1 * ten2k64[ind];
134 	  x_exp = x_exp - ind;
135 	} else {	// pad with zeros until the exponent reaches emin
136 	  ind = x_exp;
137 	  C1 = C1 * ten2k64[ind];
138 	  x_exp = EXP_MIN;
139 	}
140       }
141       if (!x_sign) {	// x > 0
142 	// add 1 ulp (add 1 to the significand)
143 	C1++;
144 	if (C1 == 0x002386f26fc10000ull) {	// if  C1 = 10^16
145 	  C1 = 0x00038d7ea4c68000ull;	// C1 = 10^15
146 	  x_exp++;
147 	}
148 	// Ok, because MAXFP = 999...99 * 10^emax was caught already
149       } else {	// x < 0
150 	// subtract 1 ulp (subtract 1 from the significand)
151 	C1--;
152 	if (C1 == 0x00038d7ea4c67fffull && x_exp != 0) {	// if  C1 = 10^15 - 1
153 	  C1 = 0x002386f26fc0ffffull;	// C1 = 10^16 - 1
154 	  x_exp--;
155 	}
156       }
157       // assemble the result
158       // if significand has 54 bits
159       if (C1 & MASK_BINARY_OR2) {
160 	res =
161 	  x_sign | (x_exp << 51) | MASK_STEERING_BITS | (C1 &
162 							 MASK_BINARY_SIG2);
163       } else {	// significand fits in 53 bits
164 	res = x_sign | (x_exp << 53) | C1;
165       }
166     }	// end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
167   }	// end x is not special and is not zero
168   BID_RETURN (res);
169 }
170 
171 /*****************************************************************************
172  *  BID64 nextdown
173  ****************************************************************************/
174 
175 #if DECIMAL_CALL_BY_REFERENCE
176 void
177 bid64_nextdown (UINT64 * pres,
178 		UINT64 *
179 		px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
180   UINT64 x = *px;
181 #else
182 UINT64
183 bid64_nextdown (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
184 		_EXC_INFO_PARAM) {
185 #endif
186 
187   UINT64 res;
188   UINT64 x_sign;
189   UINT64 x_exp;
190   BID_UI64DOUBLE tmp1;
191   int x_nr_bits;
192   int q1, ind;
193   UINT64 C1;			// C1 represents x_signif (UINT64)
194 
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
199     else
200       x = x & 0xfe03ffffffffffffull;	// clear G6-G12
201     if ((x & MASK_SNAN) == MASK_SNAN) {	// SNaN
202       // set invalid flag
203       *pfpsf |= INVALID_EXCEPTION;
204       // return quiet (SNaN)
205       res = x & 0xfdffffffffffffffull;
206     } else {	// QNaN
207       res = x;
208     }
209     BID_RETURN (res);
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
215     }
216     BID_RETURN (res);
217   }
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
225       x_exp = 0;
226       C1 = 0;
227     }
228   } else {
229     x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
230     C1 = x & MASK_BINARY_SIG1;
231   }
232 
233   // check for zeros (possibly from non-canonical values)
234   if (C1 == 0x0ull) {
235     // x is 0
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
246 
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
252 	// rounding errors
253 	if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
254 	  tmp1.d = (double) (C1 >> 32);	// exact conversion
255 	  x_nr_bits =
256 	    33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
257 	} else {	// x < 2^32
258 	  tmp1.d = (double) C1;	// exact conversion
259 	  x_nr_bits =
260 	    1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
261 	}
262       } else {	// if x < 2^53
263 	tmp1.d = (double) C1;	// exact conversion
264 	x_nr_bits =
265 	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
266       }
267       q1 = nr_digits[x_nr_bits - 1].digits;
268       if (q1 == 0) {
269 	q1 = nr_digits[x_nr_bits - 1].digits1;
270 	if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
271 	  q1++;
272       }
273       // if q1 < P16 then pad the significand with zeros
274       if (q1 < P16) {
275 	if (x_exp > (UINT64) (P16 - q1)) {
276 	  ind = P16 - q1;	// 1 <= ind <= P16 - 1
277 	  // pad with P16 - q1 zeros, until exponent = emin
278 	  // C1 = C1 * 10^ind
279 	  C1 = C1 * ten2k64[ind];
280 	  x_exp = x_exp - ind;
281 	} else {	// pad with zeros until the exponent reaches emin
282 	  ind = x_exp;
283 	  C1 = C1 * ten2k64[ind];
284 	  x_exp = EXP_MIN;
285 	}
286       }
287       if (x_sign) {	// x < 0
288 	// add 1 ulp (add 1 to the significand)
289 	C1++;
290 	if (C1 == 0x002386f26fc10000ull) {	// if  C1 = 10^16
291 	  C1 = 0x00038d7ea4c68000ull;	// C1 = 10^15
292 	  x_exp++;
293 	  // Ok, because -MAXFP = -999...99 * 10^emax was caught already
294 	}
295       } else {	// x > 0
296 	// subtract 1 ulp (subtract 1 from the significand)
297 	C1--;
298 	if (C1 == 0x00038d7ea4c67fffull && x_exp != 0) {	// if  C1 = 10^15 - 1
299 	  C1 = 0x002386f26fc0ffffull;	// C1 = 10^16 - 1
300 	  x_exp--;
301 	}
302       }
303       // assemble the result
304       // if significand has 54 bits
305       if (C1 & MASK_BINARY_OR2) {
306 	res =
307 	  x_sign | (x_exp << 51) | MASK_STEERING_BITS | (C1 &
308 							 MASK_BINARY_SIG2);
309       } else {	// significand fits in 53 bits
310 	res = x_sign | (x_exp << 53) | C1;
311       }
312     }	// end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
313   }	// end x is not special and is not zero
314   BID_RETURN (res);
315 }
316 
317 /*****************************************************************************
318  *  BID64 nextafter
319  ****************************************************************************/
320 
321 #if DECIMAL_CALL_BY_REFERENCE
322 void
323 bid64_nextafter (UINT64 * pres, UINT64 * px,
324 		 UINT64 *
325 		 py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
326   UINT64 x = *px;
327   UINT64 y = *py;
328 #else
329 UINT64
330 bid64_nextafter (UINT64 x,
331 		 UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
332 		 _EXC_INFO_PARAM) {
333 #endif
334 
335   UINT64 res;
336   UINT64 tmp1, tmp2;
337   FPSC tmp_fpsf = 0;		// dummy fpsf for calls to comparison functions
338   int res1, res2;
339 
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
344 
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
348       else
349 	x = x & 0xfe03ffffffffffffull;	// clear G6-G12
350       if ((x & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
351 	// set invalid flag
352 	*pfpsf |= INVALID_EXCEPTION;
353 	// return quiet (x)
354 	res = x & 0xfdffffffffffffffull;
355       } else {	// x is QNaN
356 	if ((y & MASK_SNAN) == MASK_SNAN) {	// y is SNAN
357 	  // set invalid flag
358 	  *pfpsf |= INVALID_EXCEPTION;
359 	}
360 	// return x
361 	res = x;
362       }
363       BID_RETURN (res);
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
367       else
368 	y = y & 0xfe03ffffffffffffull;	// clear G6-G12
369       if ((y & MASK_SNAN) == MASK_SNAN) {	// y is SNAN
370 	// set invalid flag
371 	*pfpsf |= INVALID_EXCEPTION;
372 	// return quiet (y)
373 	res = y & 0xfdffffffffffffffull;
374       } else {	// y is QNaN
375 	// return y
376 	res = y;
377       }
378       BID_RETURN (res);
379     } else {	// at least one is infinity
380       if ((x & MASK_ANY_INF) == MASK_INF) {	// x = inf
381 	x = x & (MASK_SIGN | MASK_INF);
382       }
383       if ((y & MASK_ANY_INF) == MASK_INF) {	// y = inf
384 	y = y & (MASK_SIGN | MASK_INF);
385       }
386     }
387   }
388   // neither x nor y is NaN
389 
390   // if not infinity, check for non-canonical values x (treated as zero)
391   if ((x & MASK_ANY_INF) != MASK_INF) {	// x != inf
392     // unpack x
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) {
398 	// non-canonical
399 	x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
400       }
401     } else {	// if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS) x is unch.
402       ;	// canonical
403     }
404   }
405   // no need to check for non-canonical y
406 
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);
414 #else
415   res1 =
416     bid64_quiet_equal (x,
417 		       y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
418   res2 =
419     bid64_quiet_greater (x,
420 			 y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
421 #endif
422   *pfpsf = tmp_fpsf;	// restore fpsf
423   if (res1) {	// x = y
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);
430 #else
431     res =
432       bid64_nextdown (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
433 #endif
434   } else {	// x < y
435 #if DECIMAL_CALL_BY_REFERENCE
436     bid64_nextup (&res, px _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
437 #else
438     res = bid64_nextup (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
439 #endif
440   }
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;
448   }
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
457 		       _EXC_INFO_ARG);
458   bid64_quiet_not_equal (&res2, &x,
459 			 &res _EXC_FLAGS_ARG _EXC_MASKS_ARG
460 			 _EXC_INFO_ARG);
461 #else
462   res1 =
463     bid64_quiet_greater (tmp1,
464 			 tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
465 			 _EXC_INFO_ARG);
466   res2 =
467     bid64_quiet_not_equal (x,
468 			   res _EXC_FLAGS_ARG _EXC_MASKS_ARG
469 			   _EXC_INFO_ARG);
470 #endif
471   *pfpsf = tmp_fpsf;	// restore fpsf
472   if (res1 && res2) {
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;
479   }
480   BID_RETURN (res);
481 }
482