bid64_minmax.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  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 minimum function - returns greater of two numbers
  21. *****************************************************************************/
  22. static const UINT64 mult_factor[16] = {
  23. 1ull, 10ull, 100ull, 1000ull,
  24. 10000ull, 100000ull, 1000000ull, 10000000ull,
  25. 100000000ull, 1000000000ull, 10000000000ull, 100000000000ull,
  26. 1000000000000ull, 10000000000000ull,
  27. 100000000000000ull, 1000000000000000ull
  28. };
  29. #if DECIMAL_CALL_BY_REFERENCE
  30. void
  31. bid64_minnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
  32. UINT64 x = *px;
  33. UINT64 y = *py;
  34. #else
  35. UINT64
  36. bid64_minnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
  37. #endif
  38. UINT64 res;
  39. int exp_x, exp_y;
  40. UINT64 sig_x, sig_y;
  41. UINT128 sig_n_prime;
  42. char x_is_zero = 0, y_is_zero = 0;
  43. // check for non-canonical x
  44. if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
  45. x = x & 0xfe03ffffffffffffull; // clear G6-G12
  46. if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
  47. x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  48. }
  49. } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
  50. x = x & (MASK_SIGN | MASK_INF);
  51. } else { // x is not special
  52. // check for non-canonical values - treated as zero
  53. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  54. // if the steering bits are 11, then the exponent is G[0:w+1]
  55. if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
  56. 9999999999999999ull) {
  57. // non-canonical
  58. x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
  59. } // else canonical
  60. } // else canonical
  61. }
  62. // check for non-canonical y
  63. if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
  64. y = y & 0xfe03ffffffffffffull; // clear G6-G12
  65. if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
  66. y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  67. }
  68. } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
  69. y = y & (MASK_SIGN | MASK_INF);
  70. } else { // y is not special
  71. // check for non-canonical values - treated as zero
  72. if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  73. // if the steering bits are 11, then the exponent is G[0:w+1]
  74. if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
  75. 9999999999999999ull) {
  76. // non-canonical
  77. y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
  78. } // else canonical
  79. } // else canonical
  80. }
  81. // NaN (CASE1)
  82. if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
  83. if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
  84. // if x is SNAN, then return quiet (x)
  85. *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
  86. x = x & 0xfdffffffffffffffull; // quietize x
  87. res = x;
  88. } else { // x is QNaN
  89. if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
  90. if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
  91. *pfpsf |= INVALID_EXCEPTION; // set invalid flag
  92. }
  93. res = x;
  94. } else {
  95. res = y;
  96. }
  97. }
  98. BID_RETURN (res);
  99. } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
  100. if ((y & MASK_SNAN) == MASK_SNAN) {
  101. *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
  102. y = y & 0xfdffffffffffffffull; // quietize y
  103. res = y;
  104. } else {
  105. // will return x (which is not NaN)
  106. res = x;
  107. }
  108. BID_RETURN (res);
  109. }
  110. // SIMPLE (CASE2)
  111. // if all the bits are the same, these numbers are equal, return either number
  112. if (x == y) {
  113. res = x;
  114. BID_RETURN (res);
  115. }
  116. // INFINITY (CASE3)
  117. if ((x & MASK_INF) == MASK_INF) {
  118. // if x is neg infinity, there is no way it is greater than y, return x
  119. if (((x & MASK_SIGN) == MASK_SIGN)) {
  120. res = x;
  121. BID_RETURN (res);
  122. }
  123. // x is pos infinity, return y
  124. else {
  125. res = y;
  126. BID_RETURN (res);
  127. }
  128. } else if ((y & MASK_INF) == MASK_INF) {
  129. // x is finite, so if y is positive infinity, then x is less, return y
  130. // if y is negative infinity, then x is greater, return x
  131. res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
  132. BID_RETURN (res);
  133. }
  134. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  135. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  136. exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
  137. sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  138. } else {
  139. exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
  140. sig_x = (x & MASK_BINARY_SIG1);
  141. }
  142. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  143. if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  144. exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
  145. sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  146. } else {
  147. exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
  148. sig_y = (y & MASK_BINARY_SIG1);
  149. }
  150. // ZERO (CASE4)
  151. // some properties:
  152. // (+ZERO == -ZERO) => therefore
  153. // ignore the sign, and neither number is greater
  154. // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
  155. // ignore the exponent field
  156. // (Any non-canonical # is considered 0)
  157. if (sig_x == 0) {
  158. x_is_zero = 1;
  159. }
  160. if (sig_y == 0) {
  161. y_is_zero = 1;
  162. }
  163. if (x_is_zero && y_is_zero) {
  164. // if both numbers are zero, neither is greater => return either
  165. res = y;
  166. BID_RETURN (res);
  167. } else if (x_is_zero) {
  168. // is x is zero, it is greater if Y is negative
  169. res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
  170. BID_RETURN (res);
  171. } else if (y_is_zero) {
  172. // is y is zero, X is greater if it is positive
  173. res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x;;
  174. BID_RETURN (res);
  175. }
  176. // OPPOSITE SIGN (CASE5)
  177. // now, if the sign bits differ, x is greater if y is negative
  178. if (((x ^ y) & MASK_SIGN) == MASK_SIGN) {
  179. res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
  180. BID_RETURN (res);
  181. }
  182. // REDUNDANT REPRESENTATIONS (CASE6)
  183. // if both components are either bigger or smaller,
  184. // it is clear what needs to be done
  185. if (sig_x > sig_y && exp_x >= exp_y) {
  186. res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x;
  187. BID_RETURN (res);
  188. }
  189. if (sig_x < sig_y && exp_x <= exp_y) {
  190. res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
  191. BID_RETURN (res);
  192. }
  193. // if exp_x is 15 greater than exp_y, no need for compensation
  194. if (exp_x - exp_y > 15) {
  195. res = ((x & MASK_SIGN) != MASK_SIGN) ? y : x; // difference cannot be >10^15
  196. BID_RETURN (res);
  197. }
  198. // if exp_x is 15 less than exp_y, no need for compensation
  199. if (exp_y - exp_x > 15) {
  200. res = ((x & MASK_SIGN) == MASK_SIGN) ? y : x;
  201. BID_RETURN (res);
  202. }
  203. // if |exp_x - exp_y| < 15, it comes down to the compensated significand
  204. if (exp_x > exp_y) { // to simplify the loop below,
  205. // otherwise adjust the x significand upwards
  206. __mul_64x64_to_128MACH (sig_n_prime, sig_x,
  207. mult_factor[exp_x - exp_y]);
  208. // if postitive, return whichever significand is larger
  209. // (converse if negative)
  210. if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
  211. res = y;
  212. BID_RETURN (res);
  213. }
  214. res = (((sig_n_prime.w[1] > 0)
  215. || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
  216. MASK_SIGN)) ? y : x;
  217. BID_RETURN (res);
  218. }
  219. // adjust the y significand upwards
  220. __mul_64x64_to_128MACH (sig_n_prime, sig_y,
  221. mult_factor[exp_y - exp_x]);
  222. // if postitive, return whichever significand is larger (converse if negative)
  223. if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
  224. res = y;
  225. BID_RETURN (res);
  226. }
  227. res = (((sig_n_prime.w[1] == 0)
  228. && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
  229. MASK_SIGN)) ? y : x;
  230. BID_RETURN (res);
  231. }
  232. /*****************************************************************************
  233. * BID64 minimum magnitude function - returns greater of two numbers
  234. *****************************************************************************/
  235. #if DECIMAL_CALL_BY_REFERENCE
  236. void
  237. bid64_minnum_mag (UINT64 * pres, UINT64 * px,
  238. UINT64 * py _EXC_FLAGS_PARAM) {
  239. UINT64 x = *px;
  240. UINT64 y = *py;
  241. #else
  242. UINT64
  243. bid64_minnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
  244. #endif
  245. UINT64 res;
  246. int exp_x, exp_y;
  247. UINT64 sig_x, sig_y;
  248. UINT128 sig_n_prime;
  249. // check for non-canonical x
  250. if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
  251. x = x & 0xfe03ffffffffffffull; // clear G6-G12
  252. if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
  253. x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  254. }
  255. } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
  256. x = x & (MASK_SIGN | MASK_INF);
  257. } else { // x is not special
  258. // check for non-canonical values - treated as zero
  259. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  260. // if the steering bits are 11, then the exponent is G[0:w+1]
  261. if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
  262. 9999999999999999ull) {
  263. // non-canonical
  264. x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
  265. } // else canonical
  266. } // else canonical
  267. }
  268. // check for non-canonical y
  269. if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
  270. y = y & 0xfe03ffffffffffffull; // clear G6-G12
  271. if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
  272. y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  273. }
  274. } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
  275. y = y & (MASK_SIGN | MASK_INF);
  276. } else { // y is not special
  277. // check for non-canonical values - treated as zero
  278. if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  279. // if the steering bits are 11, then the exponent is G[0:w+1]
  280. if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
  281. 9999999999999999ull) {
  282. // non-canonical
  283. y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
  284. } // else canonical
  285. } // else canonical
  286. }
  287. // NaN (CASE1)
  288. if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
  289. if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
  290. // if x is SNAN, then return quiet (x)
  291. *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
  292. x = x & 0xfdffffffffffffffull; // quietize x
  293. res = x;
  294. } else { // x is QNaN
  295. if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
  296. if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
  297. *pfpsf |= INVALID_EXCEPTION; // set invalid flag
  298. }
  299. res = x;
  300. } else {
  301. res = y;
  302. }
  303. }
  304. BID_RETURN (res);
  305. } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
  306. if ((y & MASK_SNAN) == MASK_SNAN) {
  307. *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
  308. y = y & 0xfdffffffffffffffull; // quietize y
  309. res = y;
  310. } else {
  311. // will return x (which is not NaN)
  312. res = x;
  313. }
  314. BID_RETURN (res);
  315. }
  316. // SIMPLE (CASE2)
  317. // if all the bits are the same, these numbers are equal, return either number
  318. if (x == y) {
  319. res = x;
  320. BID_RETURN (res);
  321. }
  322. // INFINITY (CASE3)
  323. if ((x & MASK_INF) == MASK_INF) {
  324. // x is infinity, its magnitude is greater than or equal to y
  325. // return x only if y is infinity and x is negative
  326. res = ((x & MASK_SIGN) == MASK_SIGN
  327. && (y & MASK_INF) == MASK_INF) ? x : y;
  328. BID_RETURN (res);
  329. } else if ((y & MASK_INF) == MASK_INF) {
  330. // y is infinity, then it must be greater in magnitude, return x
  331. res = x;
  332. BID_RETURN (res);
  333. }
  334. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  335. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  336. exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
  337. sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  338. } else {
  339. exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
  340. sig_x = (x & MASK_BINARY_SIG1);
  341. }
  342. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  343. if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  344. exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
  345. sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  346. } else {
  347. exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
  348. sig_y = (y & MASK_BINARY_SIG1);
  349. }
  350. // ZERO (CASE4)
  351. // some properties:
  352. // (+ZERO == -ZERO) => therefore
  353. // ignore the sign, and neither number is greater
  354. // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
  355. // ignore the exponent field
  356. // (Any non-canonical # is considered 0)
  357. if (sig_x == 0) {
  358. res = x; // x_is_zero, its magnitude must be smaller than y
  359. BID_RETURN (res);
  360. }
  361. if (sig_y == 0) {
  362. res = y; // y_is_zero, its magnitude must be smaller than x
  363. BID_RETURN (res);
  364. }
  365. // REDUNDANT REPRESENTATIONS (CASE6)
  366. // if both components are either bigger or smaller,
  367. // it is clear what needs to be done
  368. if (sig_x > sig_y && exp_x >= exp_y) {
  369. res = y;
  370. BID_RETURN (res);
  371. }
  372. if (sig_x < sig_y && exp_x <= exp_y) {
  373. res = x;
  374. BID_RETURN (res);
  375. }
  376. // if exp_x is 15 greater than exp_y, no need for compensation
  377. if (exp_x - exp_y > 15) {
  378. res = y; // difference cannot be greater than 10^15
  379. BID_RETURN (res);
  380. }
  381. // if exp_x is 15 less than exp_y, no need for compensation
  382. if (exp_y - exp_x > 15) {
  383. res = x;
  384. BID_RETURN (res);
  385. }
  386. // if |exp_x - exp_y| < 15, it comes down to the compensated significand
  387. if (exp_x > exp_y) { // to simplify the loop below,
  388. // otherwise adjust the x significand upwards
  389. __mul_64x64_to_128MACH (sig_n_prime, sig_x,
  390. mult_factor[exp_x - exp_y]);
  391. // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y), this is
  392. // the compensated signif.
  393. if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
  394. // two numbers are equal, return minNum(x,y)
  395. res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
  396. BID_RETURN (res);
  397. }
  398. // now, if compensated_x (sig_n_prime) is greater than y, return y,
  399. // otherwise return x
  400. res = ((sig_n_prime.w[1] != 0) || sig_n_prime.w[0] > sig_y) ? y : x;
  401. BID_RETURN (res);
  402. }
  403. // exp_y must be greater than exp_x, thus adjust the y significand upwards
  404. __mul_64x64_to_128MACH (sig_n_prime, sig_y,
  405. mult_factor[exp_y - exp_x]);
  406. if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
  407. res = ((y & MASK_SIGN) == MASK_SIGN) ? y : x;
  408. // two numbers are equal, return either
  409. BID_RETURN (res);
  410. }
  411. res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? y : x;
  412. BID_RETURN (res);
  413. }
  414. /*****************************************************************************
  415. * BID64 maximum function - returns greater of two numbers
  416. *****************************************************************************/
  417. #if DECIMAL_CALL_BY_REFERENCE
  418. void
  419. bid64_maxnum (UINT64 * pres, UINT64 * px, UINT64 * py _EXC_FLAGS_PARAM) {
  420. UINT64 x = *px;
  421. UINT64 y = *py;
  422. #else
  423. UINT64
  424. bid64_maxnum (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
  425. #endif
  426. UINT64 res;
  427. int exp_x, exp_y;
  428. UINT64 sig_x, sig_y;
  429. UINT128 sig_n_prime;
  430. char x_is_zero = 0, y_is_zero = 0;
  431. // check for non-canonical x
  432. if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
  433. x = x & 0xfe03ffffffffffffull; // clear G6-G12
  434. if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
  435. x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  436. }
  437. } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
  438. x = x & (MASK_SIGN | MASK_INF);
  439. } else { // x is not special
  440. // check for non-canonical values - treated as zero
  441. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  442. // if the steering bits are 11, then the exponent is G[0:w+1]
  443. if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
  444. 9999999999999999ull) {
  445. // non-canonical
  446. x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
  447. } // else canonical
  448. } // else canonical
  449. }
  450. // check for non-canonical y
  451. if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
  452. y = y & 0xfe03ffffffffffffull; // clear G6-G12
  453. if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
  454. y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  455. }
  456. } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
  457. y = y & (MASK_SIGN | MASK_INF);
  458. } else { // y is not special
  459. // check for non-canonical values - treated as zero
  460. if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  461. // if the steering bits are 11, then the exponent is G[0:w+1]
  462. if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
  463. 9999999999999999ull) {
  464. // non-canonical
  465. y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
  466. } // else canonical
  467. } // else canonical
  468. }
  469. // NaN (CASE1)
  470. if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
  471. if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
  472. // if x is SNAN, then return quiet (x)
  473. *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
  474. x = x & 0xfdffffffffffffffull; // quietize x
  475. res = x;
  476. } else { // x is QNaN
  477. if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
  478. if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
  479. *pfpsf |= INVALID_EXCEPTION; // set invalid flag
  480. }
  481. res = x;
  482. } else {
  483. res = y;
  484. }
  485. }
  486. BID_RETURN (res);
  487. } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
  488. if ((y & MASK_SNAN) == MASK_SNAN) {
  489. *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
  490. y = y & 0xfdffffffffffffffull; // quietize y
  491. res = y;
  492. } else {
  493. // will return x (which is not NaN)
  494. res = x;
  495. }
  496. BID_RETURN (res);
  497. }
  498. // SIMPLE (CASE2)
  499. // if all the bits are the same, these numbers are equal (not Greater).
  500. if (x == y) {
  501. res = x;
  502. BID_RETURN (res);
  503. }
  504. // INFINITY (CASE3)
  505. if ((x & MASK_INF) == MASK_INF) {
  506. // if x is neg infinity, there is no way it is greater than y, return y
  507. // x is pos infinity, it is greater, unless y is positive infinity =>
  508. // return y!=pos_infinity
  509. if (((x & MASK_SIGN) == MASK_SIGN)) {
  510. res = y;
  511. BID_RETURN (res);
  512. } else {
  513. res = (((y & MASK_INF) != MASK_INF)
  514. || ((y & MASK_SIGN) == MASK_SIGN)) ? x : y;
  515. BID_RETURN (res);
  516. }
  517. } else if ((y & MASK_INF) == MASK_INF) {
  518. // x is finite, so if y is positive infinity, then x is less, return y
  519. // if y is negative infinity, then x is greater, return x
  520. res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
  521. BID_RETURN (res);
  522. }
  523. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  524. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  525. exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
  526. sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  527. } else {
  528. exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
  529. sig_x = (x & MASK_BINARY_SIG1);
  530. }
  531. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  532. if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  533. exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
  534. sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  535. } else {
  536. exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
  537. sig_y = (y & MASK_BINARY_SIG1);
  538. }
  539. // ZERO (CASE4)
  540. // some properties:
  541. // (+ZERO == -ZERO) => therefore
  542. // ignore the sign, and neither number is greater
  543. // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
  544. // ignore the exponent field
  545. // (Any non-canonical # is considered 0)
  546. if (sig_x == 0) {
  547. x_is_zero = 1;
  548. }
  549. if (sig_y == 0) {
  550. y_is_zero = 1;
  551. }
  552. if (x_is_zero && y_is_zero) {
  553. // if both numbers are zero, neither is greater => return NOTGREATERTHAN
  554. res = y;
  555. BID_RETURN (res);
  556. } else if (x_is_zero) {
  557. // is x is zero, it is greater if Y is negative
  558. res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
  559. BID_RETURN (res);
  560. } else if (y_is_zero) {
  561. // is y is zero, X is greater if it is positive
  562. res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;;
  563. BID_RETURN (res);
  564. }
  565. // OPPOSITE SIGN (CASE5)
  566. // now, if the sign bits differ, x is greater if y is negative
  567. if (((x ^ y) & MASK_SIGN) == MASK_SIGN) {
  568. res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
  569. BID_RETURN (res);
  570. }
  571. // REDUNDANT REPRESENTATIONS (CASE6)
  572. // if both components are either bigger or smaller,
  573. // it is clear what needs to be done
  574. if (sig_x > sig_y && exp_x >= exp_y) {
  575. res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;
  576. BID_RETURN (res);
  577. }
  578. if (sig_x < sig_y && exp_x <= exp_y) {
  579. res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
  580. BID_RETURN (res);
  581. }
  582. // if exp_x is 15 greater than exp_y, no need for compensation
  583. if (exp_x - exp_y > 15) {
  584. res = ((x & MASK_SIGN) != MASK_SIGN) ? x : y;
  585. // difference cannot be > 10^15
  586. BID_RETURN (res);
  587. }
  588. // if exp_x is 15 less than exp_y, no need for compensation
  589. if (exp_y - exp_x > 15) {
  590. res = ((x & MASK_SIGN) == MASK_SIGN) ? x : y;
  591. BID_RETURN (res);
  592. }
  593. // if |exp_x - exp_y| < 15, it comes down to the compensated significand
  594. if (exp_x > exp_y) { // to simplify the loop below,
  595. // otherwise adjust the x significand upwards
  596. __mul_64x64_to_128MACH (sig_n_prime, sig_x,
  597. mult_factor[exp_x - exp_y]);
  598. // if postitive, return whichever significand is larger
  599. // (converse if negative)
  600. if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
  601. res = y;
  602. BID_RETURN (res);
  603. }
  604. res = (((sig_n_prime.w[1] > 0)
  605. || sig_n_prime.w[0] > sig_y) ^ ((x & MASK_SIGN) ==
  606. MASK_SIGN)) ? x : y;
  607. BID_RETURN (res);
  608. }
  609. // adjust the y significand upwards
  610. __mul_64x64_to_128MACH (sig_n_prime, sig_y,
  611. mult_factor[exp_y - exp_x]);
  612. // if postitive, return whichever significand is larger (converse if negative)
  613. if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
  614. res = y;
  615. BID_RETURN (res);
  616. }
  617. res = (((sig_n_prime.w[1] == 0)
  618. && (sig_x > sig_n_prime.w[0])) ^ ((x & MASK_SIGN) ==
  619. MASK_SIGN)) ? x : y;
  620. BID_RETURN (res);
  621. }
  622. /*****************************************************************************
  623. * BID64 maximum magnitude function - returns greater of two numbers
  624. *****************************************************************************/
  625. #if DECIMAL_CALL_BY_REFERENCE
  626. void
  627. bid64_maxnum_mag (UINT64 * pres, UINT64 * px,
  628. UINT64 * py _EXC_FLAGS_PARAM) {
  629. UINT64 x = *px;
  630. UINT64 y = *py;
  631. #else
  632. UINT64
  633. bid64_maxnum_mag (UINT64 x, UINT64 y _EXC_FLAGS_PARAM) {
  634. #endif
  635. UINT64 res;
  636. int exp_x, exp_y;
  637. UINT64 sig_x, sig_y;
  638. UINT128 sig_n_prime;
  639. // check for non-canonical x
  640. if ((x & MASK_NAN) == MASK_NAN) { // x is NaN
  641. x = x & 0xfe03ffffffffffffull; // clear G6-G12
  642. if ((x & 0x0003ffffffffffffull) > 999999999999999ull) {
  643. x = x & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  644. }
  645. } else if ((x & MASK_INF) == MASK_INF) { // check for Infinity
  646. x = x & (MASK_SIGN | MASK_INF);
  647. } else { // x is not special
  648. // check for non-canonical values - treated as zero
  649. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  650. // if the steering bits are 11, then the exponent is G[0:w+1]
  651. if (((x & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
  652. 9999999999999999ull) {
  653. // non-canonical
  654. x = (x & MASK_SIGN) | ((x & MASK_BINARY_EXPONENT2) << 2);
  655. } // else canonical
  656. } // else canonical
  657. }
  658. // check for non-canonical y
  659. if ((y & MASK_NAN) == MASK_NAN) { // y is NaN
  660. y = y & 0xfe03ffffffffffffull; // clear G6-G12
  661. if ((y & 0x0003ffffffffffffull) > 999999999999999ull) {
  662. y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits
  663. }
  664. } else if ((y & MASK_INF) == MASK_INF) { // check for Infinity
  665. y = y & (MASK_SIGN | MASK_INF);
  666. } else { // y is not special
  667. // check for non-canonical values - treated as zero
  668. if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  669. // if the steering bits are 11, then the exponent is G[0:w+1]
  670. if (((y & MASK_BINARY_SIG2) | MASK_BINARY_OR2) >
  671. 9999999999999999ull) {
  672. // non-canonical
  673. y = (y & MASK_SIGN) | ((y & MASK_BINARY_EXPONENT2) << 2);
  674. } // else canonical
  675. } // else canonical
  676. }
  677. // NaN (CASE1)
  678. if ((x & MASK_NAN) == MASK_NAN) { // x is NAN
  679. if ((x & MASK_SNAN) == MASK_SNAN) { // x is SNaN
  680. // if x is SNAN, then return quiet (x)
  681. *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
  682. x = x & 0xfdffffffffffffffull; // quietize x
  683. res = x;
  684. } else { // x is QNaN
  685. if ((y & MASK_NAN) == MASK_NAN) { // y is NAN
  686. if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN
  687. *pfpsf |= INVALID_EXCEPTION; // set invalid flag
  688. }
  689. res = x;
  690. } else {
  691. res = y;
  692. }
  693. }
  694. BID_RETURN (res);
  695. } else if ((y & MASK_NAN) == MASK_NAN) { // y is NaN, but x is not
  696. if ((y & MASK_SNAN) == MASK_SNAN) {
  697. *pfpsf |= INVALID_EXCEPTION; // set exception if SNaN
  698. y = y & 0xfdffffffffffffffull; // quietize y
  699. res = y;
  700. } else {
  701. // will return x (which is not NaN)
  702. res = x;
  703. }
  704. BID_RETURN (res);
  705. }
  706. // SIMPLE (CASE2)
  707. // if all the bits are the same, these numbers are equal, return either number
  708. if (x == y) {
  709. res = x;
  710. BID_RETURN (res);
  711. }
  712. // INFINITY (CASE3)
  713. if ((x & MASK_INF) == MASK_INF) {
  714. // x is infinity, its magnitude is greater than or equal to y
  715. // return y as long as x isn't negative infinity
  716. res = ((x & MASK_SIGN) == MASK_SIGN
  717. && (y & MASK_INF) == MASK_INF) ? y : x;
  718. BID_RETURN (res);
  719. } else if ((y & MASK_INF) == MASK_INF) {
  720. // y is infinity, then it must be greater in magnitude
  721. res = y;
  722. BID_RETURN (res);
  723. }
  724. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  725. if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  726. exp_x = (x & MASK_BINARY_EXPONENT2) >> 51;
  727. sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  728. } else {
  729. exp_x = (x & MASK_BINARY_EXPONENT1) >> 53;
  730. sig_x = (x & MASK_BINARY_SIG1);
  731. }
  732. // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
  733. if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
  734. exp_y = (y & MASK_BINARY_EXPONENT2) >> 51;
  735. sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
  736. } else {
  737. exp_y = (y & MASK_BINARY_EXPONENT1) >> 53;
  738. sig_y = (y & MASK_BINARY_SIG1);
  739. }
  740. // ZERO (CASE4)
  741. // some properties:
  742. // (+ZERO == -ZERO) => therefore
  743. // ignore the sign, and neither number is greater
  744. // (ZERO x 10^A == ZERO x 10^B) for any valid A, B =>
  745. // ignore the exponent field
  746. // (Any non-canonical # is considered 0)
  747. if (sig_x == 0) {
  748. res = y; // x_is_zero, its magnitude must be smaller than y
  749. BID_RETURN (res);
  750. }
  751. if (sig_y == 0) {
  752. res = x; // y_is_zero, its magnitude must be smaller than x
  753. BID_RETURN (res);
  754. }
  755. // REDUNDANT REPRESENTATIONS (CASE6)
  756. // if both components are either bigger or smaller,
  757. // it is clear what needs to be done
  758. if (sig_x > sig_y && exp_x >= exp_y) {
  759. res = x;
  760. BID_RETURN (res);
  761. }
  762. if (sig_x < sig_y && exp_x <= exp_y) {
  763. res = y;
  764. BID_RETURN (res);
  765. }
  766. // if exp_x is 15 greater than exp_y, no need for compensation
  767. if (exp_x - exp_y > 15) {
  768. res = x; // difference cannot be greater than 10^15
  769. BID_RETURN (res);
  770. }
  771. // if exp_x is 15 less than exp_y, no need for compensation
  772. if (exp_y - exp_x > 15) {
  773. res = y;
  774. BID_RETURN (res);
  775. }
  776. // if |exp_x - exp_y| < 15, it comes down to the compensated significand
  777. if (exp_x > exp_y) { // to simplify the loop below,
  778. // otherwise adjust the x significand upwards
  779. __mul_64x64_to_128MACH (sig_n_prime, sig_x,
  780. mult_factor[exp_x - exp_y]);
  781. // now, sig_n_prime has: sig_x * 10^(exp_x-exp_y),
  782. // this is the compensated signif.
  783. if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_y)) {
  784. // two numbers are equal, return maxNum(x,y)
  785. res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
  786. BID_RETURN (res);
  787. }
  788. // now, if compensated_x (sig_n_prime) is greater than y return y,
  789. // otherwise return x
  790. res = ((sig_n_prime.w[1] != 0) || sig_n_prime.w[0] > sig_y) ? x : y;
  791. BID_RETURN (res);
  792. }
  793. // exp_y must be greater than exp_x, thus adjust the y significand upwards
  794. __mul_64x64_to_128MACH (sig_n_prime, sig_y,
  795. mult_factor[exp_y - exp_x]);
  796. if (sig_n_prime.w[1] == 0 && (sig_n_prime.w[0] == sig_x)) {
  797. res = ((y & MASK_SIGN) == MASK_SIGN) ? x : y;
  798. // two numbers are equal, return either
  799. BID_RETURN (res);
  800. }
  801. res = ((sig_n_prime.w[1] == 0) && (sig_x > sig_n_prime.w[0])) ? x : y;
  802. BID_RETURN (res);
  803. }