bid128_next.c 21 KB

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