bid_inline_add.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. /* Copyright (C) 2007-2015 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. /*****************************************************************************
  19. *
  20. * Helper add functions (for fma)
  21. *
  22. * __BID_INLINE__ UINT64 get_add64(
  23. * UINT64 sign_x, int exponent_x, UINT64 coefficient_x,
  24. * UINT64 sign_y, int exponent_y, UINT64 coefficient_y,
  25. * int rounding_mode)
  26. *
  27. * __BID_INLINE__ UINT64 get_add128(
  28. * UINT64 sign_x, int exponent_x, UINT64 coefficient_x,
  29. * UINT64 sign_y, int final_exponent_y, UINT128 CY,
  30. * int extra_digits, int rounding_mode)
  31. *
  32. *****************************************************************************
  33. *
  34. * Algorithm description:
  35. *
  36. * get_add64: same as BID64 add, but arguments are unpacked and there
  37. * are no special case checks
  38. *
  39. * get_add128: add 64-bit coefficient to 128-bit product (which contains
  40. * 16+extra_digits decimal digits),
  41. * return BID64 result
  42. * - the exponents are compared and the two coefficients are
  43. * properly aligned for addition/subtraction
  44. * - multiple paths are needed
  45. * - final result exponent is calculated and the lower term is
  46. * rounded first if necessary, to avoid manipulating
  47. * coefficients longer than 128 bits
  48. *
  49. ****************************************************************************/
  50. #ifndef _INLINE_BID_ADD_H_
  51. #define _INLINE_BID_ADD_H_
  52. #include "bid_internal.h"
  53. #define MAX_FORMAT_DIGITS 16
  54. #define DECIMAL_EXPONENT_BIAS 398
  55. #define MASK_BINARY_EXPONENT 0x7ff0000000000000ull
  56. #define BINARY_EXPONENT_BIAS 0x3ff
  57. #define UPPER_EXPON_LIMIT 51
  58. ///////////////////////////////////////////////////////////////////////
  59. //
  60. // get_add64() is essentially the same as bid_add(), except that
  61. // the arguments are unpacked
  62. //
  63. //////////////////////////////////////////////////////////////////////
  64. __BID_INLINE__ UINT64
  65. get_add64 (UINT64 sign_x, int exponent_x, UINT64 coefficient_x,
  66. UINT64 sign_y, int exponent_y, UINT64 coefficient_y,
  67. int rounding_mode, unsigned *fpsc) {
  68. UINT128 CA, CT, CT_new;
  69. UINT64 sign_a, sign_b, coefficient_a, coefficient_b, sign_s, sign_ab,
  70. rem_a;
  71. UINT64 saved_ca, saved_cb, C0_64, C64, remainder_h, T1, carry, tmp,
  72. C64_new;
  73. int_double tempx;
  74. int exponent_a, exponent_b, diff_dec_expon;
  75. int bin_expon_ca, extra_digits, amount, scale_k, scale_ca;
  76. unsigned rmode, status;
  77. // sort arguments by exponent
  78. if (exponent_x <= exponent_y) {
  79. sign_a = sign_y;
  80. exponent_a = exponent_y;
  81. coefficient_a = coefficient_y;
  82. sign_b = sign_x;
  83. exponent_b = exponent_x;
  84. coefficient_b = coefficient_x;
  85. } else {
  86. sign_a = sign_x;
  87. exponent_a = exponent_x;
  88. coefficient_a = coefficient_x;
  89. sign_b = sign_y;
  90. exponent_b = exponent_y;
  91. coefficient_b = coefficient_y;
  92. }
  93. // exponent difference
  94. diff_dec_expon = exponent_a - exponent_b;
  95. /* get binary coefficients of x and y */
  96. //--- get number of bits in the coefficients of x and y ---
  97. tempx.d = (double) coefficient_a;
  98. bin_expon_ca = ((tempx.i & MASK_BINARY_EXPONENT) >> 52) - 0x3ff;
  99. if (!coefficient_a) {
  100. return get_BID64 (sign_b, exponent_b, coefficient_b, rounding_mode,
  101. fpsc);
  102. }
  103. if (diff_dec_expon > MAX_FORMAT_DIGITS) {
  104. // normalize a to a 16-digit coefficient
  105. scale_ca = estimate_decimal_digits[bin_expon_ca];
  106. if (coefficient_a >= power10_table_128[scale_ca].w[0])
  107. scale_ca++;
  108. scale_k = 16 - scale_ca;
  109. coefficient_a *= power10_table_128[scale_k].w[0];
  110. diff_dec_expon -= scale_k;
  111. exponent_a -= scale_k;
  112. /* get binary coefficients of x and y */
  113. //--- get number of bits in the coefficients of x and y ---
  114. tempx.d = (double) coefficient_a;
  115. bin_expon_ca = ((tempx.i & MASK_BINARY_EXPONENT) >> 52) - 0x3ff;
  116. if (diff_dec_expon > MAX_FORMAT_DIGITS) {
  117. #ifdef SET_STATUS_FLAGS
  118. if (coefficient_b) {
  119. __set_status_flags (fpsc, INEXACT_EXCEPTION);
  120. }
  121. #endif
  122. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  123. #ifndef IEEE_ROUND_NEAREST
  124. if (((rounding_mode) & 3) && coefficient_b) // not ROUNDING_TO_NEAREST
  125. {
  126. switch (rounding_mode) {
  127. case ROUNDING_DOWN:
  128. if (sign_b) {
  129. coefficient_a -= ((((SINT64) sign_a) >> 63) | 1);
  130. if (coefficient_a < 1000000000000000ull) {
  131. exponent_a--;
  132. coefficient_a = 9999999999999999ull;
  133. } else if (coefficient_a >= 10000000000000000ull) {
  134. exponent_a++;
  135. coefficient_a = 1000000000000000ull;
  136. }
  137. }
  138. break;
  139. case ROUNDING_UP:
  140. if (!sign_b) {
  141. coefficient_a += ((((SINT64) sign_a) >> 63) | 1);
  142. if (coefficient_a < 1000000000000000ull) {
  143. exponent_a--;
  144. coefficient_a = 9999999999999999ull;
  145. } else if (coefficient_a >= 10000000000000000ull) {
  146. exponent_a++;
  147. coefficient_a = 1000000000000000ull;
  148. }
  149. }
  150. break;
  151. default: // RZ
  152. if (sign_a != sign_b) {
  153. coefficient_a--;
  154. if (coefficient_a < 1000000000000000ull) {
  155. exponent_a--;
  156. coefficient_a = 9999999999999999ull;
  157. }
  158. }
  159. break;
  160. }
  161. } else
  162. #endif
  163. #endif
  164. // check special case here
  165. if ((coefficient_a == 1000000000000000ull)
  166. && (diff_dec_expon == MAX_FORMAT_DIGITS + 1)
  167. && (sign_a ^ sign_b)
  168. && (coefficient_b > 5000000000000000ull)) {
  169. coefficient_a = 9999999999999999ull;
  170. exponent_a--;
  171. }
  172. return get_BID64 (sign_a, exponent_a, coefficient_a,
  173. rounding_mode, fpsc);
  174. }
  175. }
  176. // test whether coefficient_a*10^(exponent_a-exponent_b) may exceed 2^62
  177. if (bin_expon_ca + estimate_bin_expon[diff_dec_expon] < 60) {
  178. // coefficient_a*10^(exponent_a-exponent_b)<2^63
  179. // multiply by 10^(exponent_a-exponent_b)
  180. coefficient_a *= power10_table_128[diff_dec_expon].w[0];
  181. // sign mask
  182. sign_b = ((SINT64) sign_b) >> 63;
  183. // apply sign to coeff. of b
  184. coefficient_b = (coefficient_b + sign_b) ^ sign_b;
  185. // apply sign to coefficient a
  186. sign_a = ((SINT64) sign_a) >> 63;
  187. coefficient_a = (coefficient_a + sign_a) ^ sign_a;
  188. coefficient_a += coefficient_b;
  189. // get sign
  190. sign_s = ((SINT64) coefficient_a) >> 63;
  191. coefficient_a = (coefficient_a + sign_s) ^ sign_s;
  192. sign_s &= 0x8000000000000000ull;
  193. // coefficient_a < 10^16 ?
  194. if (coefficient_a < power10_table_128[MAX_FORMAT_DIGITS].w[0]) {
  195. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  196. #ifndef IEEE_ROUND_NEAREST
  197. if (rounding_mode == ROUNDING_DOWN && (!coefficient_a)
  198. && sign_a != sign_b)
  199. sign_s = 0x8000000000000000ull;
  200. #endif
  201. #endif
  202. return get_BID64 (sign_s, exponent_b, coefficient_a,
  203. rounding_mode, fpsc);
  204. }
  205. // otherwise rounding is necessary
  206. // already know coefficient_a<10^19
  207. // coefficient_a < 10^17 ?
  208. if (coefficient_a < power10_table_128[17].w[0])
  209. extra_digits = 1;
  210. else if (coefficient_a < power10_table_128[18].w[0])
  211. extra_digits = 2;
  212. else
  213. extra_digits = 3;
  214. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  215. #ifndef IEEE_ROUND_NEAREST
  216. rmode = rounding_mode;
  217. if (sign_s && (unsigned) (rmode - 1) < 2)
  218. rmode = 3 - rmode;
  219. #else
  220. rmode = 0;
  221. #endif
  222. #else
  223. rmode = 0;
  224. #endif
  225. coefficient_a += round_const_table[rmode][extra_digits];
  226. // get P*(2^M[extra_digits])/10^extra_digits
  227. __mul_64x64_to_128 (CT, coefficient_a,
  228. reciprocals10_64[extra_digits]);
  229. // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
  230. amount = short_recip_scale[extra_digits];
  231. C64 = CT.w[1] >> amount;
  232. } else {
  233. // coefficient_a*10^(exponent_a-exponent_b) is large
  234. sign_s = sign_a;
  235. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  236. #ifndef IEEE_ROUND_NEAREST
  237. rmode = rounding_mode;
  238. if (sign_s && (unsigned) (rmode - 1) < 2)
  239. rmode = 3 - rmode;
  240. #else
  241. rmode = 0;
  242. #endif
  243. #else
  244. rmode = 0;
  245. #endif
  246. // check whether we can take faster path
  247. scale_ca = estimate_decimal_digits[bin_expon_ca];
  248. sign_ab = sign_a ^ sign_b;
  249. sign_ab = ((SINT64) sign_ab) >> 63;
  250. // T1 = 10^(16-diff_dec_expon)
  251. T1 = power10_table_128[16 - diff_dec_expon].w[0];
  252. // get number of digits in coefficient_a
  253. //P_ca = power10_table_128[scale_ca].w[0];
  254. //P_ca_m1 = power10_table_128[scale_ca-1].w[0];
  255. if (coefficient_a >= power10_table_128[scale_ca].w[0]) {
  256. scale_ca++;
  257. //P_ca_m1 = P_ca;
  258. //P_ca = power10_table_128[scale_ca].w[0];
  259. }
  260. scale_k = 16 - scale_ca;
  261. // apply sign
  262. //Ts = (T1 + sign_ab) ^ sign_ab;
  263. // test range of ca
  264. //X = coefficient_a + Ts - P_ca_m1;
  265. // addition
  266. saved_ca = coefficient_a - T1;
  267. coefficient_a =
  268. (SINT64) saved_ca *(SINT64) power10_table_128[scale_k].w[0];
  269. extra_digits = diff_dec_expon - scale_k;
  270. // apply sign
  271. saved_cb = (coefficient_b + sign_ab) ^ sign_ab;
  272. // add 10^16 and rounding constant
  273. coefficient_b =
  274. saved_cb + 10000000000000000ull +
  275. round_const_table[rmode][extra_digits];
  276. // get P*(2^M[extra_digits])/10^extra_digits
  277. __mul_64x64_to_128 (CT, coefficient_b,
  278. reciprocals10_64[extra_digits]);
  279. // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
  280. amount = short_recip_scale[extra_digits];
  281. C0_64 = CT.w[1] >> amount;
  282. // result coefficient
  283. C64 = C0_64 + coefficient_a;
  284. // filter out difficult (corner) cases
  285. // the following test is equivalent to
  286. // ( (initial_coefficient_a + Ts) < P_ca &&
  287. // (initial_coefficient_a + Ts) > P_ca_m1 ),
  288. // which ensures the number of digits in coefficient_a does not change
  289. // after adding (the appropriately scaled and rounded) coefficient_b
  290. if ((UINT64) (C64 - 1000000000000000ull - 1) >
  291. 9000000000000000ull - 2) {
  292. if (C64 >= 10000000000000000ull) {
  293. // result has more than 16 digits
  294. if (!scale_k) {
  295. // must divide coeff_a by 10
  296. saved_ca = saved_ca + T1;
  297. __mul_64x64_to_128 (CA, saved_ca, 0x3333333333333334ull);
  298. //reciprocals10_64[1]);
  299. coefficient_a = CA.w[1] >> 1;
  300. rem_a =
  301. saved_ca - (coefficient_a << 3) - (coefficient_a << 1);
  302. coefficient_a = coefficient_a - T1;
  303. saved_cb +=
  304. /*90000000000000000 */ +rem_a *
  305. power10_table_128[diff_dec_expon].w[0];
  306. } else
  307. coefficient_a =
  308. (SINT64) (saved_ca - T1 -
  309. (T1 << 3)) * (SINT64) power10_table_128[scale_k -
  310. 1].w[0];
  311. extra_digits++;
  312. coefficient_b =
  313. saved_cb + 100000000000000000ull +
  314. round_const_table[rmode][extra_digits];
  315. // get P*(2^M[extra_digits])/10^extra_digits
  316. __mul_64x64_to_128 (CT, coefficient_b,
  317. reciprocals10_64[extra_digits]);
  318. // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
  319. amount = short_recip_scale[extra_digits];
  320. C0_64 = CT.w[1] >> amount;
  321. // result coefficient
  322. C64 = C0_64 + coefficient_a;
  323. } else if (C64 <= 1000000000000000ull) {
  324. // less than 16 digits in result
  325. coefficient_a =
  326. (SINT64) saved_ca *(SINT64) power10_table_128[scale_k +
  327. 1].w[0];
  328. //extra_digits --;
  329. exponent_b--;
  330. coefficient_b =
  331. (saved_cb << 3) + (saved_cb << 1) + 100000000000000000ull +
  332. round_const_table[rmode][extra_digits];
  333. // get P*(2^M[extra_digits])/10^extra_digits
  334. __mul_64x64_to_128 (CT_new, coefficient_b,
  335. reciprocals10_64[extra_digits]);
  336. // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
  337. amount = short_recip_scale[extra_digits];
  338. C0_64 = CT_new.w[1] >> amount;
  339. // result coefficient
  340. C64_new = C0_64 + coefficient_a;
  341. if (C64_new < 10000000000000000ull) {
  342. C64 = C64_new;
  343. #ifdef SET_STATUS_FLAGS
  344. CT = CT_new;
  345. #endif
  346. } else
  347. exponent_b++;
  348. }
  349. }
  350. }
  351. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  352. #ifndef IEEE_ROUND_NEAREST
  353. if (rmode == 0) //ROUNDING_TO_NEAREST
  354. #endif
  355. if (C64 & 1) {
  356. // check whether fractional part of initial_P/10^extra_digits
  357. // is exactly .5
  358. // this is the same as fractional part of
  359. // (initial_P + 0.5*10^extra_digits)/10^extra_digits is exactly zero
  360. // get remainder
  361. remainder_h = CT.w[1] << (64 - amount);
  362. // test whether fractional part is 0
  363. if (!remainder_h && (CT.w[0] < reciprocals10_64[extra_digits])) {
  364. C64--;
  365. }
  366. }
  367. #endif
  368. #ifdef SET_STATUS_FLAGS
  369. status = INEXACT_EXCEPTION;
  370. // get remainder
  371. remainder_h = CT.w[1] << (64 - amount);
  372. switch (rmode) {
  373. case ROUNDING_TO_NEAREST:
  374. case ROUNDING_TIES_AWAY:
  375. // test whether fractional part is 0
  376. if ((remainder_h == 0x8000000000000000ull)
  377. && (CT.w[0] < reciprocals10_64[extra_digits]))
  378. status = EXACT_STATUS;
  379. break;
  380. case ROUNDING_DOWN:
  381. case ROUNDING_TO_ZERO:
  382. if (!remainder_h && (CT.w[0] < reciprocals10_64[extra_digits]))
  383. status = EXACT_STATUS;
  384. break;
  385. default:
  386. // round up
  387. __add_carry_out (tmp, carry, CT.w[0],
  388. reciprocals10_64[extra_digits]);
  389. if ((remainder_h >> (64 - amount)) + carry >=
  390. (((UINT64) 1) << amount))
  391. status = EXACT_STATUS;
  392. break;
  393. }
  394. __set_status_flags (fpsc, status);
  395. #endif
  396. return get_BID64 (sign_s, exponent_b + extra_digits, C64,
  397. rounding_mode, fpsc);
  398. }
  399. ///////////////////////////////////////////////////////////////////
  400. // round 128-bit coefficient and return result in BID64 format
  401. // do not worry about midpoint cases
  402. //////////////////////////////////////////////////////////////////
  403. static UINT64
  404. __bid_simple_round64_sticky (UINT64 sign, int exponent, UINT128 P,
  405. int extra_digits, int rounding_mode,
  406. unsigned *fpsc) {
  407. UINT128 Q_high, Q_low, C128;
  408. UINT64 C64;
  409. int amount, rmode;
  410. rmode = rounding_mode;
  411. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  412. #ifndef IEEE_ROUND_NEAREST
  413. if (sign && (unsigned) (rmode - 1) < 2)
  414. rmode = 3 - rmode;
  415. #endif
  416. #endif
  417. __add_128_64 (P, P, round_const_table[rmode][extra_digits]);
  418. // get P*(2^M[extra_digits])/10^extra_digits
  419. __mul_128x128_full (Q_high, Q_low, P,
  420. reciprocals10_128[extra_digits]);
  421. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  422. amount = recip_scale[extra_digits];
  423. __shr_128 (C128, Q_high, amount);
  424. C64 = __low_64 (C128);
  425. #ifdef SET_STATUS_FLAGS
  426. __set_status_flags (fpsc, INEXACT_EXCEPTION);
  427. #endif
  428. return get_BID64 (sign, exponent, C64, rounding_mode, fpsc);
  429. }
  430. ///////////////////////////////////////////////////////////////////
  431. // round 128-bit coefficient and return result in BID64 format
  432. ///////////////////////////////////////////////////////////////////
  433. static UINT64
  434. __bid_full_round64 (UINT64 sign, int exponent, UINT128 P,
  435. int extra_digits, int rounding_mode,
  436. unsigned *fpsc) {
  437. UINT128 Q_high, Q_low, C128, Stemp, PU;
  438. UINT64 remainder_h, C64, carry, CY;
  439. int amount, amount2, rmode, status = 0;
  440. if (exponent < 0) {
  441. if (exponent >= -16 && (extra_digits + exponent < 0)) {
  442. extra_digits = -exponent;
  443. #ifdef SET_STATUS_FLAGS
  444. if (extra_digits > 0) {
  445. rmode = rounding_mode;
  446. if (sign && (unsigned) (rmode - 1) < 2)
  447. rmode = 3 - rmode;
  448. __add_128_128 (PU, P,
  449. round_const_table_128[rmode][extra_digits]);
  450. if (__unsigned_compare_gt_128
  451. (power10_table_128[extra_digits + 15], PU))
  452. status = UNDERFLOW_EXCEPTION;
  453. }
  454. #endif
  455. }
  456. }
  457. if (extra_digits > 0) {
  458. exponent += extra_digits;
  459. rmode = rounding_mode;
  460. if (sign && (unsigned) (rmode - 1) < 2)
  461. rmode = 3 - rmode;
  462. __add_128_128 (P, P, round_const_table_128[rmode][extra_digits]);
  463. // get P*(2^M[extra_digits])/10^extra_digits
  464. __mul_128x128_full (Q_high, Q_low, P,
  465. reciprocals10_128[extra_digits]);
  466. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  467. amount = recip_scale[extra_digits];
  468. __shr_128_long (C128, Q_high, amount);
  469. C64 = __low_64 (C128);
  470. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  471. #ifndef IEEE_ROUND_NEAREST
  472. if (rmode == 0) //ROUNDING_TO_NEAREST
  473. #endif
  474. if (C64 & 1) {
  475. // check whether fractional part of initial_P/10^extra_digits
  476. // is exactly .5
  477. // get remainder
  478. amount2 = 64 - amount;
  479. remainder_h = 0;
  480. remainder_h--;
  481. remainder_h >>= amount2;
  482. remainder_h = remainder_h & Q_high.w[0];
  483. if (!remainder_h
  484. && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
  485. || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
  486. && Q_low.w[0] <
  487. reciprocals10_128[extra_digits].w[0]))) {
  488. C64--;
  489. }
  490. }
  491. #endif
  492. #ifdef SET_STATUS_FLAGS
  493. status |= INEXACT_EXCEPTION;
  494. // get remainder
  495. remainder_h = Q_high.w[0] << (64 - amount);
  496. switch (rmode) {
  497. case ROUNDING_TO_NEAREST:
  498. case ROUNDING_TIES_AWAY:
  499. // test whether fractional part is 0
  500. if (remainder_h == 0x8000000000000000ull
  501. && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
  502. || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
  503. && Q_low.w[0] <
  504. reciprocals10_128[extra_digits].w[0])))
  505. status = EXACT_STATUS;
  506. break;
  507. case ROUNDING_DOWN:
  508. case ROUNDING_TO_ZERO:
  509. if (!remainder_h
  510. && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
  511. || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
  512. && Q_low.w[0] <
  513. reciprocals10_128[extra_digits].w[0])))
  514. status = EXACT_STATUS;
  515. break;
  516. default:
  517. // round up
  518. __add_carry_out (Stemp.w[0], CY, Q_low.w[0],
  519. reciprocals10_128[extra_digits].w[0]);
  520. __add_carry_in_out (Stemp.w[1], carry, Q_low.w[1],
  521. reciprocals10_128[extra_digits].w[1], CY);
  522. if ((remainder_h >> (64 - amount)) + carry >=
  523. (((UINT64) 1) << amount))
  524. status = EXACT_STATUS;
  525. }
  526. __set_status_flags (fpsc, status);
  527. #endif
  528. } else {
  529. C64 = P.w[0];
  530. if (!C64) {
  531. sign = 0;
  532. if (rounding_mode == ROUNDING_DOWN)
  533. sign = 0x8000000000000000ull;
  534. }
  535. }
  536. return get_BID64 (sign, exponent, C64, rounding_mode, fpsc);
  537. }
  538. /////////////////////////////////////////////////////////////////////////////////
  539. // round 192-bit coefficient (P, remainder_P) and return result in BID64 format
  540. // the lowest 64 bits (remainder_P) are used for midpoint checking only
  541. ////////////////////////////////////////////////////////////////////////////////
  542. static UINT64
  543. __bid_full_round64_remainder (UINT64 sign, int exponent, UINT128 P,
  544. int extra_digits, UINT64 remainder_P,
  545. int rounding_mode, unsigned *fpsc,
  546. unsigned uf_status) {
  547. UINT128 Q_high, Q_low, C128, Stemp;
  548. UINT64 remainder_h, C64, carry, CY;
  549. int amount, amount2, rmode, status = uf_status;
  550. rmode = rounding_mode;
  551. if (sign && (unsigned) (rmode - 1) < 2)
  552. rmode = 3 - rmode;
  553. if (rmode == ROUNDING_UP && remainder_P) {
  554. P.w[0]++;
  555. if (!P.w[0])
  556. P.w[1]++;
  557. }
  558. if (extra_digits) {
  559. __add_128_64 (P, P, round_const_table[rmode][extra_digits]);
  560. // get P*(2^M[extra_digits])/10^extra_digits
  561. __mul_128x128_full (Q_high, Q_low, P,
  562. reciprocals10_128[extra_digits]);
  563. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  564. amount = recip_scale[extra_digits];
  565. __shr_128 (C128, Q_high, amount);
  566. C64 = __low_64 (C128);
  567. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  568. #ifndef IEEE_ROUND_NEAREST
  569. if (rmode == 0) //ROUNDING_TO_NEAREST
  570. #endif
  571. if (!remainder_P && (C64 & 1)) {
  572. // check whether fractional part of initial_P/10^extra_digits
  573. // is exactly .5
  574. // get remainder
  575. amount2 = 64 - amount;
  576. remainder_h = 0;
  577. remainder_h--;
  578. remainder_h >>= amount2;
  579. remainder_h = remainder_h & Q_high.w[0];
  580. if (!remainder_h
  581. && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
  582. || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
  583. && Q_low.w[0] <
  584. reciprocals10_128[extra_digits].w[0]))) {
  585. C64--;
  586. }
  587. }
  588. #endif
  589. #ifdef SET_STATUS_FLAGS
  590. status |= INEXACT_EXCEPTION;
  591. if (!remainder_P) {
  592. // get remainder
  593. remainder_h = Q_high.w[0] << (64 - amount);
  594. switch (rmode) {
  595. case ROUNDING_TO_NEAREST:
  596. case ROUNDING_TIES_AWAY:
  597. // test whether fractional part is 0
  598. if (remainder_h == 0x8000000000000000ull
  599. && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
  600. || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
  601. && Q_low.w[0] <
  602. reciprocals10_128[extra_digits].w[0])))
  603. status = EXACT_STATUS;
  604. break;
  605. case ROUNDING_DOWN:
  606. case ROUNDING_TO_ZERO:
  607. if (!remainder_h
  608. && (Q_low.w[1] < reciprocals10_128[extra_digits].w[1]
  609. || (Q_low.w[1] == reciprocals10_128[extra_digits].w[1]
  610. && Q_low.w[0] <
  611. reciprocals10_128[extra_digits].w[0])))
  612. status = EXACT_STATUS;
  613. break;
  614. default:
  615. // round up
  616. __add_carry_out (Stemp.w[0], CY, Q_low.w[0],
  617. reciprocals10_128[extra_digits].w[0]);
  618. __add_carry_in_out (Stemp.w[1], carry, Q_low.w[1],
  619. reciprocals10_128[extra_digits].w[1], CY);
  620. if ((remainder_h >> (64 - amount)) + carry >=
  621. (((UINT64) 1) << amount))
  622. status = EXACT_STATUS;
  623. }
  624. }
  625. __set_status_flags (fpsc, status);
  626. #endif
  627. } else {
  628. C64 = P.w[0];
  629. #ifdef SET_STATUS_FLAGS
  630. if (remainder_P) {
  631. __set_status_flags (fpsc, uf_status | INEXACT_EXCEPTION);
  632. }
  633. #endif
  634. }
  635. return get_BID64 (sign, exponent + extra_digits, C64, rounding_mode,
  636. fpsc);
  637. }
  638. ///////////////////////////////////////////////////////////////////
  639. // get P/10^extra_digits
  640. // result fits in 64 bits
  641. ///////////////////////////////////////////////////////////////////
  642. __BID_INLINE__ UINT64
  643. __truncate (UINT128 P, int extra_digits)
  644. // extra_digits <= 16
  645. {
  646. UINT128 Q_high, Q_low, C128;
  647. UINT64 C64;
  648. int amount;
  649. // get P*(2^M[extra_digits])/10^extra_digits
  650. __mul_128x128_full (Q_high, Q_low, P,
  651. reciprocals10_128[extra_digits]);
  652. // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
  653. amount = recip_scale[extra_digits];
  654. __shr_128 (C128, Q_high, amount);
  655. C64 = __low_64 (C128);
  656. return C64;
  657. }
  658. ///////////////////////////////////////////////////////////////////
  659. // return number of decimal digits in 128-bit value X
  660. ///////////////////////////////////////////////////////////////////
  661. __BID_INLINE__ int
  662. __get_dec_digits64 (UINT128 X) {
  663. int_double tempx;
  664. int digits_x, bin_expon_cx;
  665. if (!X.w[1]) {
  666. //--- get number of bits in the coefficients of x and y ---
  667. tempx.d = (double) X.w[0];
  668. bin_expon_cx = ((tempx.i & MASK_BINARY_EXPONENT) >> 52) - 0x3ff;
  669. // get number of decimal digits in the coeff_x
  670. digits_x = estimate_decimal_digits[bin_expon_cx];
  671. if (X.w[0] >= power10_table_128[digits_x].w[0])
  672. digits_x++;
  673. return digits_x;
  674. }
  675. tempx.d = (double) X.w[1];
  676. bin_expon_cx = ((tempx.i & MASK_BINARY_EXPONENT) >> 52) - 0x3ff;
  677. // get number of decimal digits in the coeff_x
  678. digits_x = estimate_decimal_digits[bin_expon_cx + 64];
  679. if (__unsigned_compare_ge_128 (X, power10_table_128[digits_x]))
  680. digits_x++;
  681. return digits_x;
  682. }
  683. ////////////////////////////////////////////////////////////////////////////////
  684. //
  685. // add 64-bit coefficient to 128-bit coefficient, return result in BID64 format
  686. //
  687. ////////////////////////////////////////////////////////////////////////////////
  688. __BID_INLINE__ UINT64
  689. get_add128 (UINT64 sign_x, int exponent_x, UINT64 coefficient_x,
  690. UINT64 sign_y, int final_exponent_y, UINT128 CY,
  691. int extra_digits, int rounding_mode, unsigned *fpsc) {
  692. UINT128 CY_L, CX, FS, F, CT, ST, T2;
  693. UINT64 CYh, CY0L, T, S, coefficient_y, remainder_y;
  694. SINT64 D = 0;
  695. int_double tempx;
  696. int diff_dec_expon, extra_digits2, exponent_y, status;
  697. int extra_dx, diff_dec2, bin_expon_cx, digits_x, rmode;
  698. // CY has more than 16 decimal digits
  699. exponent_y = final_exponent_y - extra_digits;
  700. #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
  701. rounding_mode = 0;
  702. #endif
  703. #ifdef IEEE_ROUND_NEAREST
  704. rounding_mode = 0;
  705. #endif
  706. if (exponent_x > exponent_y) {
  707. // normalize x
  708. //--- get number of bits in the coefficients of x and y ---
  709. tempx.d = (double) coefficient_x;
  710. bin_expon_cx = ((tempx.i & MASK_BINARY_EXPONENT) >> 52) - 0x3ff;
  711. // get number of decimal digits in the coeff_x
  712. digits_x = estimate_decimal_digits[bin_expon_cx];
  713. if (coefficient_x >= power10_table_128[digits_x].w[0])
  714. digits_x++;
  715. extra_dx = 16 - digits_x;
  716. coefficient_x *= power10_table_128[extra_dx].w[0];
  717. if ((sign_x ^ sign_y) && (coefficient_x == 1000000000000000ull)) {
  718. extra_dx++;
  719. coefficient_x = 10000000000000000ull;
  720. }
  721. exponent_x -= extra_dx;
  722. if (exponent_x > exponent_y) {
  723. // exponent_x > exponent_y
  724. diff_dec_expon = exponent_x - exponent_y;
  725. if (exponent_x <= final_exponent_y + 1) {
  726. __mul_64x64_to_128 (CX, coefficient_x,
  727. power10_table_128[diff_dec_expon].w[0]);
  728. if (sign_x == sign_y) {
  729. __add_128_128 (CT, CY, CX);
  730. if ((exponent_x >
  731. final_exponent_y) /*&& (final_exponent_y>0) */ )
  732. extra_digits++;
  733. if (__unsigned_compare_ge_128
  734. (CT, power10_table_128[16 + extra_digits]))
  735. extra_digits++;
  736. } else {
  737. __sub_128_128 (CT, CY, CX);
  738. if (((SINT64) CT.w[1]) < 0) {
  739. CT.w[0] = 0 - CT.w[0];
  740. CT.w[1] = 0 - CT.w[1];
  741. if (CT.w[0])
  742. CT.w[1]--;
  743. sign_y = sign_x;
  744. } else if (!(CT.w[1] | CT.w[0])) {
  745. sign_y =
  746. (rounding_mode !=
  747. ROUNDING_DOWN) ? 0 : 0x8000000000000000ull;
  748. }
  749. if ((exponent_x + 1 >=
  750. final_exponent_y) /*&& (final_exponent_y>=0) */ ) {
  751. extra_digits = __get_dec_digits64 (CT) - 16;
  752. if (extra_digits <= 0) {
  753. if (!CT.w[0] && rounding_mode == ROUNDING_DOWN)
  754. sign_y = 0x8000000000000000ull;
  755. return get_BID64 (sign_y, exponent_y, CT.w[0],
  756. rounding_mode, fpsc);
  757. }
  758. } else
  759. if (__unsigned_compare_gt_128
  760. (power10_table_128[15 + extra_digits], CT))
  761. extra_digits--;
  762. }
  763. return __bid_full_round64 (sign_y, exponent_y, CT, extra_digits,
  764. rounding_mode, fpsc);
  765. }
  766. // diff_dec2+extra_digits is the number of digits to eliminate from
  767. // argument CY
  768. diff_dec2 = exponent_x - final_exponent_y;
  769. if (diff_dec2 >= 17) {
  770. #ifndef IEEE_ROUND_NEAREST
  771. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  772. if ((rounding_mode) & 3) {
  773. switch (rounding_mode) {
  774. case ROUNDING_UP:
  775. if (!sign_y) {
  776. D = ((SINT64) (sign_x ^ sign_y)) >> 63;
  777. D = D + D + 1;
  778. coefficient_x += D;
  779. }
  780. break;
  781. case ROUNDING_DOWN:
  782. if (sign_y) {
  783. D = ((SINT64) (sign_x ^ sign_y)) >> 63;
  784. D = D + D + 1;
  785. coefficient_x += D;
  786. }
  787. break;
  788. case ROUNDING_TO_ZERO:
  789. if (sign_y != sign_x) {
  790. D = 0 - 1;
  791. coefficient_x += D;
  792. }
  793. break;
  794. }
  795. if (coefficient_x < 1000000000000000ull) {
  796. coefficient_x -= D;
  797. coefficient_x =
  798. D + (coefficient_x << 1) + (coefficient_x << 3);
  799. exponent_x--;
  800. }
  801. }
  802. #endif
  803. #endif
  804. #ifdef SET_STATUS_FLAGS
  805. if (CY.w[1] | CY.w[0])
  806. __set_status_flags (fpsc, INEXACT_EXCEPTION);
  807. #endif
  808. return get_BID64 (sign_x, exponent_x, coefficient_x,
  809. rounding_mode, fpsc);
  810. }
  811. // here exponent_x <= 16+final_exponent_y
  812. // truncate CY to 16 dec. digits
  813. CYh = __truncate (CY, extra_digits);
  814. // get remainder
  815. T = power10_table_128[extra_digits].w[0];
  816. __mul_64x64_to_64 (CY0L, CYh, T);
  817. remainder_y = CY.w[0] - CY0L;
  818. // align coeff_x, CYh
  819. __mul_64x64_to_128 (CX, coefficient_x,
  820. power10_table_128[diff_dec2].w[0]);
  821. if (sign_x == sign_y) {
  822. __add_128_64 (CT, CX, CYh);
  823. if (__unsigned_compare_ge_128
  824. (CT, power10_table_128[16 + diff_dec2]))
  825. diff_dec2++;
  826. } else {
  827. if (remainder_y)
  828. CYh++;
  829. __sub_128_64 (CT, CX, CYh);
  830. if (__unsigned_compare_gt_128
  831. (power10_table_128[15 + diff_dec2], CT))
  832. diff_dec2--;
  833. }
  834. return __bid_full_round64_remainder (sign_x, final_exponent_y, CT,
  835. diff_dec2, remainder_y,
  836. rounding_mode, fpsc, 0);
  837. }
  838. }
  839. // Here (exponent_x <= exponent_y)
  840. {
  841. diff_dec_expon = exponent_y - exponent_x;
  842. if (diff_dec_expon > MAX_FORMAT_DIGITS) {
  843. rmode = rounding_mode;
  844. if ((sign_x ^ sign_y)) {
  845. if (!CY.w[0])
  846. CY.w[1]--;
  847. CY.w[0]--;
  848. if (__unsigned_compare_gt_128
  849. (power10_table_128[15 + extra_digits], CY)) {
  850. if (rmode & 3) {
  851. extra_digits--;
  852. final_exponent_y--;
  853. } else {
  854. CY.w[0] = 1000000000000000ull;
  855. CY.w[1] = 0;
  856. extra_digits = 0;
  857. }
  858. }
  859. }
  860. __scale128_10 (CY, CY);
  861. extra_digits++;
  862. CY.w[0] |= 1;
  863. return __bid_simple_round64_sticky (sign_y, final_exponent_y, CY,
  864. extra_digits, rmode, fpsc);
  865. }
  866. // apply sign to coeff_x
  867. sign_x ^= sign_y;
  868. sign_x = ((SINT64) sign_x) >> 63;
  869. CX.w[0] = (coefficient_x + sign_x) ^ sign_x;
  870. CX.w[1] = sign_x;
  871. // check whether CY (rounded to 16 digits) and CX have
  872. // any digits in the same position
  873. diff_dec2 = final_exponent_y - exponent_x;
  874. if (diff_dec2 <= 17) {
  875. // align CY to 10^ex
  876. S = power10_table_128[diff_dec_expon].w[0];
  877. __mul_64x128_short (CY_L, S, CY);
  878. __add_128_128 (ST, CY_L, CX);
  879. extra_digits2 = __get_dec_digits64 (ST) - 16;
  880. return __bid_full_round64 (sign_y, exponent_x, ST, extra_digits2,
  881. rounding_mode, fpsc);
  882. }
  883. // truncate CY to 16 dec. digits
  884. CYh = __truncate (CY, extra_digits);
  885. // get remainder
  886. T = power10_table_128[extra_digits].w[0];
  887. __mul_64x64_to_64 (CY0L, CYh, T);
  888. coefficient_y = CY.w[0] - CY0L;
  889. // add rounding constant
  890. rmode = rounding_mode;
  891. if (sign_y && (unsigned) (rmode - 1) < 2)
  892. rmode = 3 - rmode;
  893. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  894. #ifndef IEEE_ROUND_NEAREST
  895. if (!(rmode & 3)) //ROUNDING_TO_NEAREST
  896. #endif
  897. #endif
  898. {
  899. coefficient_y += round_const_table[rmode][extra_digits];
  900. }
  901. // align coefficient_y, coefficient_x
  902. S = power10_table_128[diff_dec_expon].w[0];
  903. __mul_64x64_to_128 (F, coefficient_y, S);
  904. // fraction
  905. __add_128_128 (FS, F, CX);
  906. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  907. #ifndef IEEE_ROUND_NEAREST
  908. if (rmode == 0) //ROUNDING_TO_NEAREST
  909. #endif
  910. {
  911. // rounding code, here RN_EVEN
  912. // 10^(extra_digits+diff_dec_expon)
  913. T2 = power10_table_128[diff_dec_expon + extra_digits];
  914. if (__unsigned_compare_gt_128 (FS, T2)
  915. || ((CYh & 1) && __test_equal_128 (FS, T2))) {
  916. CYh++;
  917. __sub_128_128 (FS, FS, T2);
  918. }
  919. }
  920. #endif
  921. #ifndef IEEE_ROUND_NEAREST
  922. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  923. if (rmode == 4) //ROUNDING_TO_NEAREST
  924. #endif
  925. {
  926. // rounding code, here RN_AWAY
  927. // 10^(extra_digits+diff_dec_expon)
  928. T2 = power10_table_128[diff_dec_expon + extra_digits];
  929. if (__unsigned_compare_ge_128 (FS, T2)) {
  930. CYh++;
  931. __sub_128_128 (FS, FS, T2);
  932. }
  933. }
  934. #endif
  935. #ifndef IEEE_ROUND_NEAREST
  936. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  937. switch (rmode) {
  938. case ROUNDING_DOWN:
  939. case ROUNDING_TO_ZERO:
  940. if ((SINT64) FS.w[1] < 0) {
  941. CYh--;
  942. if (CYh < 1000000000000000ull) {
  943. CYh = 9999999999999999ull;
  944. final_exponent_y--;
  945. }
  946. } else {
  947. T2 = power10_table_128[diff_dec_expon + extra_digits];
  948. if (__unsigned_compare_ge_128 (FS, T2)) {
  949. CYh++;
  950. __sub_128_128 (FS, FS, T2);
  951. }
  952. }
  953. break;
  954. case ROUNDING_UP:
  955. if ((SINT64) FS.w[1] < 0)
  956. break;
  957. T2 = power10_table_128[diff_dec_expon + extra_digits];
  958. if (__unsigned_compare_gt_128 (FS, T2)) {
  959. CYh += 2;
  960. __sub_128_128 (FS, FS, T2);
  961. } else if ((FS.w[1] == T2.w[1]) && (FS.w[0] == T2.w[0])) {
  962. CYh++;
  963. FS.w[1] = FS.w[0] = 0;
  964. } else if (FS.w[1] | FS.w[0])
  965. CYh++;
  966. break;
  967. }
  968. #endif
  969. #endif
  970. #ifdef SET_STATUS_FLAGS
  971. status = INEXACT_EXCEPTION;
  972. #ifndef IEEE_ROUND_NEAREST
  973. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  974. if (!(rmode & 3))
  975. #endif
  976. #endif
  977. {
  978. // RN modes
  979. if ((FS.w[1] ==
  980. round_const_table_128[0][diff_dec_expon + extra_digits].w[1])
  981. && (FS.w[0] ==
  982. round_const_table_128[0][diff_dec_expon +
  983. extra_digits].w[0]))
  984. status = EXACT_STATUS;
  985. }
  986. #ifndef IEEE_ROUND_NEAREST
  987. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  988. else if (!FS.w[1] && !FS.w[0])
  989. status = EXACT_STATUS;
  990. #endif
  991. #endif
  992. __set_status_flags (fpsc, status);
  993. #endif
  994. return get_BID64 (sign_y, final_exponent_y, CYh, rounding_mode,
  995. fpsc);
  996. }
  997. }
  998. //////////////////////////////////////////////////////////////////////////
  999. //
  1000. // If coefficient_z is less than 16 digits long, normalize to 16 digits
  1001. //
  1002. /////////////////////////////////////////////////////////////////////////
  1003. static UINT64
  1004. BID_normalize (UINT64 sign_z, int exponent_z,
  1005. UINT64 coefficient_z, UINT64 round_dir, int round_flag,
  1006. int rounding_mode, unsigned *fpsc) {
  1007. SINT64 D;
  1008. int_double tempx;
  1009. int digits_z, bin_expon, scale, rmode;
  1010. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  1011. #ifndef IEEE_ROUND_NEAREST
  1012. rmode = rounding_mode;
  1013. if (sign_z && (unsigned) (rmode - 1) < 2)
  1014. rmode = 3 - rmode;
  1015. #else
  1016. if (coefficient_z >= power10_table_128[15].w[0])
  1017. return z;
  1018. #endif
  1019. #endif
  1020. //--- get number of bits in the coefficients of x and y ---
  1021. tempx.d = (double) coefficient_z;
  1022. bin_expon = ((tempx.i & MASK_BINARY_EXPONENT) >> 52) - 0x3ff;
  1023. // get number of decimal digits in the coeff_x
  1024. digits_z = estimate_decimal_digits[bin_expon];
  1025. if (coefficient_z >= power10_table_128[digits_z].w[0])
  1026. digits_z++;
  1027. scale = 16 - digits_z;
  1028. exponent_z -= scale;
  1029. if (exponent_z < 0) {
  1030. scale += exponent_z;
  1031. exponent_z = 0;
  1032. }
  1033. coefficient_z *= power10_table_128[scale].w[0];
  1034. #ifdef SET_STATUS_FLAGS
  1035. if (round_flag) {
  1036. __set_status_flags (fpsc, INEXACT_EXCEPTION);
  1037. if (coefficient_z < 1000000000000000ull)
  1038. __set_status_flags (fpsc, UNDERFLOW_EXCEPTION);
  1039. else if ((coefficient_z == 1000000000000000ull) && !exponent_z
  1040. && ((SINT64) (round_dir ^ sign_z) < 0) && round_flag
  1041. && (rmode == ROUNDING_DOWN || rmode == ROUNDING_TO_ZERO))
  1042. __set_status_flags (fpsc, UNDERFLOW_EXCEPTION);
  1043. }
  1044. #endif
  1045. #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
  1046. #ifndef IEEE_ROUND_NEAREST
  1047. if (round_flag && (rmode & 3)) {
  1048. D = round_dir ^ sign_z;
  1049. if (rmode == ROUNDING_UP) {
  1050. if (D >= 0)
  1051. coefficient_z++;
  1052. } else {
  1053. if (D < 0)
  1054. coefficient_z--;
  1055. if (coefficient_z < 1000000000000000ull && exponent_z) {
  1056. coefficient_z = 9999999999999999ull;
  1057. exponent_z--;
  1058. }
  1059. }
  1060. }
  1061. #endif
  1062. #endif
  1063. return get_BID64 (sign_z, exponent_z, coefficient_z, rounding_mode,
  1064. fpsc);
  1065. }
  1066. //////////////////////////////////////////////////////////////////////////
  1067. //
  1068. // 0*10^ey + cz*10^ez, ey<ez
  1069. //
  1070. //////////////////////////////////////////////////////////////////////////
  1071. __BID_INLINE__ UINT64
  1072. add_zero64 (int exponent_y, UINT64 sign_z, int exponent_z,
  1073. UINT64 coefficient_z, unsigned *prounding_mode,
  1074. unsigned *fpsc) {
  1075. int_double tempx;
  1076. int bin_expon, scale_k, scale_cz;
  1077. int diff_expon;
  1078. diff_expon = exponent_z - exponent_y;
  1079. tempx.d = (double) coefficient_z;
  1080. bin_expon = ((tempx.i & MASK_BINARY_EXPONENT) >> 52) - 0x3ff;
  1081. scale_cz = estimate_decimal_digits[bin_expon];
  1082. if (coefficient_z >= power10_table_128[scale_cz].w[0])
  1083. scale_cz++;
  1084. scale_k = 16 - scale_cz;
  1085. if (diff_expon < scale_k)
  1086. scale_k = diff_expon;
  1087. coefficient_z *= power10_table_128[scale_k].w[0];
  1088. return get_BID64 (sign_z, exponent_z - scale_k, coefficient_z,
  1089. *prounding_mode, fpsc);
  1090. }
  1091. #endif