bid64_next.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
  2. This file is part of GCC.
  3. GCC is free software; you can redistribute it and/or modify it under
  4. the terms of the GNU General Public License as published by the Free
  5. Software Foundation; either version 3, or (at your option) any later
  6. version.
  7. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  8. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  9. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  10. for more details.
  11. Under Section 7 of GPL version 3, you are granted additional
  12. permissions described in the GCC Runtime Library Exception, version
  13. 3.1, as published by the Free Software Foundation.
  14. You should have received a copy of the GNU General Public License and
  15. a copy of the GCC Runtime Library Exception along with this program;
  16. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  17. <http://www.gnu.org/licenses/>. */
  18. #include "bid_internal.h"
  19. /*****************************************************************************
  20. * BID64 nextup
  21. ****************************************************************************/
  22. #if DECIMAL_CALL_BY_REFERENCE
  23. void
  24. bid64_nextup (UINT64 * pres,
  25. UINT64 *
  26. px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
  27. UINT64 x = *px;
  28. #else
  29. UINT64
  30. bid64_nextup (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  31. _EXC_INFO_PARAM) {
  32. #endif
  33. UINT64 res;
  34. UINT64 x_sign;
  35. UINT64 x_exp;
  36. BID_UI64DOUBLE tmp1;
  37. int x_nr_bits;
  38. int q1, ind;
  39. UINT64 C1; // C1 represents x_signif (UINT64)
  40. // check for NaNs and infinities
  41. if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
  42. if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
  43. x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  44. else
  45. x = x & 0xfe03ffffffffffffull; // clear G6-G12
  46. if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
  47. // set invalid flag
  48. *pfpsf |= INVALID_EXCEPTION;
  49. // return quiet (SNaN)
  50. res = x & 0xfdffffffffffffffull;
  51. } else { // QNaN
  52. res = x;
  53. }
  54. BID_RETURN (res);
  55. } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
  56. if (!(x & 0x8000000000000000ull)) { // x is +inf
  57. res = 0x7800000000000000ull;
  58. } else { // x is -inf
  59. res = 0xf7fb86f26fc0ffffull; // -MAXFP = -999...99 * 10^emax
  60. }
  61. BID_RETURN (res);
  62. }
  63. // unpack the argument
  64. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  65. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  66. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  67. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  68. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  69. if (C1 > 9999999999999999ull) { // non-canonical
  70. x_exp = 0;
  71. C1 = 0;
  72. }
  73. } else {
  74. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  75. C1 = x & MASK_BINARY_SIG1;
  76. }
  77. // check for zeros (possibly from non-canonical values)
  78. if (C1 == 0x0ull) {
  79. // x is 0
  80. res = 0x0000000000000001ull; // MINFP = 1 * 10^emin
  81. } else { // x is not special and is not zero
  82. if (x == 0x77fb86f26fc0ffffull) {
  83. // x = +MAXFP = 999...99 * 10^emax
  84. res = 0x7800000000000000ull; // +inf
  85. } else if (x == 0x8000000000000001ull) {
  86. // x = -MINFP = 1...99 * 10^emin
  87. res = 0x8000000000000000ull; // -0
  88. } else { // -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
  89. // can add/subtract 1 ulp to the significand
  90. // Note: we could check here if x >= 10^16 to speed up the case q1 =16
  91. // q1 = nr. of decimal digits in x (1 <= q1 <= 54)
  92. // determine first the nr. of bits in x
  93. if (C1 >= MASK_BINARY_OR2) { // x >= 2^53
  94. // split the 64-bit value in two 32-bit halves to avoid rounding errors
  95. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  96. tmp1.d = (double) (C1 >> 32); // exact conversion
  97. x_nr_bits =
  98. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  99. } else { // x < 2^32
  100. tmp1.d = (double) C1; // exact conversion
  101. x_nr_bits =
  102. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  103. }
  104. } else { // if x < 2^53
  105. tmp1.d = (double) C1; // exact conversion
  106. x_nr_bits =
  107. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  108. }
  109. q1 = nr_digits[x_nr_bits - 1].digits;
  110. if (q1 == 0) {
  111. q1 = nr_digits[x_nr_bits - 1].digits1;
  112. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  113. q1++;
  114. }
  115. // if q1 < P16 then pad the significand with zeros
  116. if (q1 < P16) {
  117. if (x_exp > (UINT64) (P16 - q1)) {
  118. ind = P16 - q1; // 1 <= ind <= P16 - 1
  119. // pad with P16 - q1 zeros, until exponent = emin
  120. // C1 = C1 * 10^ind
  121. C1 = C1 * ten2k64[ind];
  122. x_exp = x_exp - ind;
  123. } else { // pad with zeros until the exponent reaches emin
  124. ind = x_exp;
  125. C1 = C1 * ten2k64[ind];
  126. x_exp = EXP_MIN;
  127. }
  128. }
  129. if (!x_sign) { // x > 0
  130. // add 1 ulp (add 1 to the significand)
  131. C1++;
  132. if (C1 == 0x002386f26fc10000ull) { // if C1 = 10^16
  133. C1 = 0x00038d7ea4c68000ull; // C1 = 10^15
  134. x_exp++;
  135. }
  136. // Ok, because MAXFP = 999...99 * 10^emax was caught already
  137. } else { // x < 0
  138. // subtract 1 ulp (subtract 1 from the significand)
  139. C1--;
  140. if (C1 == 0x00038d7ea4c67fffull && x_exp != 0) { // if C1 = 10^15 - 1
  141. C1 = 0x002386f26fc0ffffull; // C1 = 10^16 - 1
  142. x_exp--;
  143. }
  144. }
  145. // assemble the result
  146. // if significand has 54 bits
  147. if (C1 & MASK_BINARY_OR2) {
  148. res =
  149. x_sign | (x_exp << 51) | MASK_STEERING_BITS | (C1 &
  150. MASK_BINARY_SIG2);
  151. } else { // significand fits in 53 bits
  152. res = x_sign | (x_exp << 53) | C1;
  153. }
  154. } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
  155. } // end x is not special and is not zero
  156. BID_RETURN (res);
  157. }
  158. /*****************************************************************************
  159. * BID64 nextdown
  160. ****************************************************************************/
  161. #if DECIMAL_CALL_BY_REFERENCE
  162. void
  163. bid64_nextdown (UINT64 * pres,
  164. UINT64 *
  165. px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
  166. UINT64 x = *px;
  167. #else
  168. UINT64
  169. bid64_nextdown (UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  170. _EXC_INFO_PARAM) {
  171. #endif
  172. UINT64 res;
  173. UINT64 x_sign;
  174. UINT64 x_exp;
  175. BID_UI64DOUBLE tmp1;
  176. int x_nr_bits;
  177. int q1, ind;
  178. UINT64 C1; // C1 represents x_signif (UINT64)
  179. // check for NaNs and infinities
  180. if ((x & MASK_NAN) == MASK_NAN) { // check for NaN
  181. if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
  182. x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  183. else
  184. x = x & 0xfe03ffffffffffffull; // clear G6-G12
  185. if ((x & MASK_SNAN) == MASK_SNAN) { // SNaN
  186. // set invalid flag
  187. *pfpsf |= INVALID_EXCEPTION;
  188. // return quiet (SNaN)
  189. res = x & 0xfdffffffffffffffull;
  190. } else { // QNaN
  191. res = x;
  192. }
  193. BID_RETURN (res);
  194. } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
  195. if (x & 0x8000000000000000ull) { // x is -inf
  196. res = 0xf800000000000000ull;
  197. } else { // x is +inf
  198. res = 0x77fb86f26fc0ffffull; // +MAXFP = +999...99 * 10^emax
  199. }
  200. BID_RETURN (res);
  201. }
  202. // unpack the argument
  203. x_sign = x & MASK_SIGN; // 0 for positive, MASK_SIGN for negative
  204. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  205. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  206. x_exp = (x & MASK_BINARY_EXPONENT2) >> 51; // biased
  207. C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  208. if (C1 > 9999999999999999ull) { // non-canonical
  209. x_exp = 0;
  210. C1 = 0;
  211. }
  212. } else {
  213. x_exp = (x & MASK_BINARY_EXPONENT1) >> 53; // biased
  214. C1 = x & MASK_BINARY_SIG1;
  215. }
  216. // check for zeros (possibly from non-canonical values)
  217. if (C1 == 0x0ull) {
  218. // x is 0
  219. res = 0x8000000000000001ull; // -MINFP = -1 * 10^emin
  220. } else { // x is not special and is not zero
  221. if (x == 0xf7fb86f26fc0ffffull) {
  222. // x = -MAXFP = -999...99 * 10^emax
  223. res = 0xf800000000000000ull; // -inf
  224. } else if (x == 0x0000000000000001ull) {
  225. // x = +MINFP = 1...99 * 10^emin
  226. res = 0x0000000000000000ull; // -0
  227. } else { // -MAXFP + 1ulp <= x <= -MINFP OR MINFP + 1 ulp <= x <= MAXFP
  228. // can add/subtract 1 ulp to the significand
  229. // Note: we could check here if x >= 10^16 to speed up the case q1 =16
  230. // q1 = nr. of decimal digits in x (1 <= q1 <= 16)
  231. // determine first the nr. of bits in x
  232. if (C1 >= 0x0020000000000000ull) { // x >= 2^53
  233. // split the 64-bit value in two 32-bit halves to avoid
  234. // rounding errors
  235. if (C1 >= 0x0000000100000000ull) { // x >= 2^32
  236. tmp1.d = (double) (C1 >> 32); // exact conversion
  237. x_nr_bits =
  238. 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  239. } else { // x < 2^32
  240. tmp1.d = (double) C1; // exact conversion
  241. x_nr_bits =
  242. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  243. }
  244. } else { // if x < 2^53
  245. tmp1.d = (double) C1; // exact conversion
  246. x_nr_bits =
  247. 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
  248. }
  249. q1 = nr_digits[x_nr_bits - 1].digits;
  250. if (q1 == 0) {
  251. q1 = nr_digits[x_nr_bits - 1].digits1;
  252. if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
  253. q1++;
  254. }
  255. // if q1 < P16 then pad the significand with zeros
  256. if (q1 < P16) {
  257. if (x_exp > (UINT64) (P16 - q1)) {
  258. ind = P16 - q1; // 1 <= ind <= P16 - 1
  259. // pad with P16 - q1 zeros, until exponent = emin
  260. // C1 = C1 * 10^ind
  261. C1 = C1 * ten2k64[ind];
  262. x_exp = x_exp - ind;
  263. } else { // pad with zeros until the exponent reaches emin
  264. ind = x_exp;
  265. C1 = C1 * ten2k64[ind];
  266. x_exp = EXP_MIN;
  267. }
  268. }
  269. if (x_sign) { // x < 0
  270. // add 1 ulp (add 1 to the significand)
  271. C1++;
  272. if (C1 == 0x002386f26fc10000ull) { // if C1 = 10^16
  273. C1 = 0x00038d7ea4c68000ull; // C1 = 10^15
  274. x_exp++;
  275. // Ok, because -MAXFP = -999...99 * 10^emax was caught already
  276. }
  277. } else { // x > 0
  278. // subtract 1 ulp (subtract 1 from the significand)
  279. C1--;
  280. if (C1 == 0x00038d7ea4c67fffull && x_exp != 0) { // if C1 = 10^15 - 1
  281. C1 = 0x002386f26fc0ffffull; // C1 = 10^16 - 1
  282. x_exp--;
  283. }
  284. }
  285. // assemble the result
  286. // if significand has 54 bits
  287. if (C1 & MASK_BINARY_OR2) {
  288. res =
  289. x_sign | (x_exp << 51) | MASK_STEERING_BITS | (C1 &
  290. MASK_BINARY_SIG2);
  291. } else { // significand fits in 53 bits
  292. res = x_sign | (x_exp << 53) | C1;
  293. }
  294. } // end -MAXFP <= x <= -MINFP - 1 ulp OR MINFP <= x <= MAXFP - 1 ulp
  295. } // end x is not special and is not zero
  296. BID_RETURN (res);
  297. }
  298. /*****************************************************************************
  299. * BID64 nextafter
  300. ****************************************************************************/
  301. #if DECIMAL_CALL_BY_REFERENCE
  302. void
  303. bid64_nextafter (UINT64 * pres, UINT64 * px,
  304. UINT64 *
  305. py _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
  306. UINT64 x = *px;
  307. UINT64 y = *py;
  308. #else
  309. UINT64
  310. bid64_nextafter (UINT64 x,
  311. UINT64 y _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  312. _EXC_INFO_PARAM) {
  313. #endif
  314. UINT64 res;
  315. UINT64 tmp1, tmp2;
  316. FPSC tmp_fpsf = 0; // dummy fpsf for calls to comparison functions
  317. int res1, res2;
  318. // check for NaNs or infinities
  319. if (((x & MASK_SPECIAL) == MASK_SPECIAL) ||
  320. ((y & MASK_SPECIAL) == MASK_SPECIAL)) {
  321. // x is NaN or infinity or y is NaN or infinity
  322. if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
  323. if ((x & 0x0003ffffffffffffull) > 999999999999999ull)
  324. x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  325. else
  326. x = x & 0xfe03ffffffffffffull; // clear G6-G12
  327. if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNAN
  328. // set invalid flag
  329. *pfpsf |= INVALID_EXCEPTION;
  330. // return quiet (x)
  331. res = x & 0xfdffffffffffffffull;
  332. } else { // x is QNaN
  333. if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
  334. // set invalid flag
  335. *pfpsf |= INVALID_EXCEPTION;
  336. }
  337. // return x
  338. res = x;
  339. }
  340. BID_RETURN (res);
  341. } else if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
  342. if ((y & 0x0003ffffffffffffull) > 999999999999999ull)
  343. y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  344. else
  345. y = y & 0xfe03ffffffffffffull; // clear G6-G12
  346. if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
  347. // set invalid flag
  348. *pfpsf |= INVALID_EXCEPTION;
  349. // return quiet (y)
  350. res = y & 0xfdffffffffffffffull;
  351. } else { // y is QNaN
  352. // return y
  353. res = y;
  354. }
  355. BID_RETURN (res);
  356. } else { // at least one is infinity
  357. if ((x & MASK_ANY_INF) == MASK_INF) { // x = inf
  358. x = x & (MASK_SIGN | MASK_INF);
  359. }
  360. if ((y & MASK_ANY_INF) == MASK_INF) { // y = inf
  361. y = y & (MASK_SIGN | MASK_INF);
  362. }
  363. }
  364. }
  365. // neither x nor y is NaN
  366. // if not infinity, check for non-canonical values x (treated as zero)
  367. if ((x & MASK_ANY_INF) != MASK_INF) { // x != inf
  368. // unpack x
  369. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  370. // if the steering bits are 11 (condition will be 0), then
  371. // the exponent is G[0:w+1]
  372. if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
  373. 9999999999999999ull) {
  374. // non-canonical
  375. x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
  376. }
  377. } else { // if ((x & MASK_STEERING_BITS) != MASK_STEERING_BITS) x is unch.
  378. ; // canonical
  379. }
  380. }
  381. // no need to check for non-canonical y
  382. // neither x nor y is NaN
  383. tmp_fpsf = *pfpsf; // save fpsf
  384. #if DECIMAL_CALL_BY_REFERENCE
  385. bid64_quiet_equal (&res1, px,
  386. py _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  387. bid64_quiet_greater (&res2, px,
  388. py _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  389. #else
  390. res1 =
  391. bid64_quiet_equal (x,
  392. y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  393. res2 =
  394. bid64_quiet_greater (x,
  395. y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  396. #endif
  397. *pfpsf = tmp_fpsf; // restore fpsf
  398. if (res1) { // x = y
  399. // return x with the sign of y
  400. res = (y & 0x8000000000000000ull) | (x & 0x7fffffffffffffffull);
  401. } else if (res2) { // x > y
  402. #if DECIMAL_CALL_BY_REFERENCE
  403. bid64_nextdown (&res,
  404. px _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  405. #else
  406. res =
  407. bid64_nextdown (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  408. #endif
  409. } else { // x < y
  410. #if DECIMAL_CALL_BY_REFERENCE
  411. bid64_nextup (&res, px _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  412. #else
  413. res = bid64_nextup (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  414. #endif
  415. }
  416. // if the operand x is finite but the result is infinite, signal
  417. // overflow and inexact
  418. if (((x & MASK_INF) != MASK_INF) && ((res & MASK_INF) == MASK_INF)) {
  419. // set the inexact flag
  420. *pfpsf |= INEXACT_EXCEPTION;
  421. // set the overflow flag
  422. *pfpsf |= OVERFLOW_EXCEPTION;
  423. }
  424. // if the result is in (-10^emin, 10^emin), and is different from the
  425. // operand x, signal underflow and inexact
  426. tmp1 = 0x00038d7ea4c68000ull; // +100...0[16] * 10^emin
  427. tmp2 = res & 0x7fffffffffffffffull;
  428. tmp_fpsf = *pfpsf; // save fpsf
  429. #if DECIMAL_CALL_BY_REFERENCE
  430. bid64_quiet_greater (&res1, &tmp1,
  431. &tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
  432. _EXC_INFO_ARG);
  433. bid64_quiet_not_equal (&res2, &x,
  434. &res _EXC_FLAGS_ARG _EXC_MASKS_ARG
  435. _EXC_INFO_ARG);
  436. #else
  437. res1 =
  438. bid64_quiet_greater (tmp1,
  439. tmp2 _EXC_FLAGS_ARG _EXC_MASKS_ARG
  440. _EXC_INFO_ARG);
  441. res2 =
  442. bid64_quiet_not_equal (x,
  443. res _EXC_FLAGS_ARG _EXC_MASKS_ARG
  444. _EXC_INFO_ARG);
  445. #endif
  446. *pfpsf = tmp_fpsf; // restore fpsf
  447. if (res1 && res2) {
  448. // if (bid64_quiet_greater (tmp1, tmp2, &tmp_fpsf) &&
  449. // bid64_quiet_not_equal (x, res, &tmp_fpsf)) {
  450. // set the inexact flag
  451. *pfpsf |= INEXACT_EXCEPTION;
  452. // set the underflow flag
  453. *pfpsf |= UNDERFLOW_EXCEPTION;
  454. }
  455. BID_RETURN (res);
  456. }