op-common.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. #define _FP_DECL(wc, X) \
  2. _FP_I_TYPE X##_c, X##_s, X##_e; \
  3. _FP_FRAC_DECL_##wc(X)
  4. /*
  5. * Finish truely unpacking a native fp value by classifying the kind
  6. * of fp value and normalizing both the exponent and the fraction.
  7. */
  8. #define _FP_UNPACK_CANONICAL(fs, wc, X) \
  9. do { \
  10. switch (X##_e) \
  11. { \
  12. default: \
  13. _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs; \
  14. _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
  15. X##_e -= _FP_EXPBIAS_##fs; \
  16. X##_c = FP_CLS_NORMAL; \
  17. break; \
  18. \
  19. case 0: \
  20. if (_FP_FRAC_ZEROP_##wc(X)) \
  21. X##_c = FP_CLS_ZERO; \
  22. else \
  23. { \
  24. /* a denormalized number */ \
  25. _FP_I_TYPE _shift; \
  26. _FP_FRAC_CLZ_##wc(_shift, X); \
  27. _shift -= _FP_FRACXBITS_##fs; \
  28. _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
  29. X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
  30. X##_c = FP_CLS_NORMAL; \
  31. } \
  32. break; \
  33. \
  34. case _FP_EXPMAX_##fs: \
  35. if (_FP_FRAC_ZEROP_##wc(X)) \
  36. X##_c = FP_CLS_INF; \
  37. else \
  38. /* we don't differentiate between signaling and quiet nans */ \
  39. X##_c = FP_CLS_NAN; \
  40. break; \
  41. } \
  42. } while (0)
  43. /*
  44. * Before packing the bits back into the native fp result, take care
  45. * of such mundane things as rounding and overflow. Also, for some
  46. * kinds of fp values, the original parts may not have been fully
  47. * extracted -- but that is ok, we can regenerate them now.
  48. */
  49. #define _FP_PACK_CANONICAL(fs, wc, X) \
  50. ({int __ret = 0; \
  51. switch (X##_c) \
  52. { \
  53. case FP_CLS_NORMAL: \
  54. X##_e += _FP_EXPBIAS_##fs; \
  55. if (X##_e > 0) \
  56. { \
  57. __ret |= _FP_ROUND(wc, X); \
  58. if (_FP_FRAC_OVERP_##wc(fs, X)) \
  59. { \
  60. _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1)); \
  61. X##_e++; \
  62. } \
  63. else \
  64. _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
  65. if (X##_e >= _FP_EXPMAX_##fs) \
  66. { \
  67. /* overflow to infinity */ \
  68. X##_e = _FP_EXPMAX_##fs; \
  69. _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
  70. __ret |= EFLAG_OVERFLOW; \
  71. } \
  72. } \
  73. else \
  74. { \
  75. /* we've got a denormalized number */ \
  76. X##_e = -X##_e + 1; \
  77. if (X##_e <= _FP_WFRACBITS_##fs) \
  78. { \
  79. _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
  80. _FP_FRAC_SLL_##wc(X, 1); \
  81. if (_FP_FRAC_OVERP_##wc(fs, X)) \
  82. { \
  83. X##_e = 1; \
  84. _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
  85. } \
  86. else \
  87. { \
  88. X##_e = 0; \
  89. _FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1); \
  90. __ret |= EFLAG_UNDERFLOW; \
  91. } \
  92. } \
  93. else \
  94. { \
  95. /* underflow to zero */ \
  96. X##_e = 0; \
  97. _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
  98. __ret |= EFLAG_UNDERFLOW; \
  99. } \
  100. } \
  101. break; \
  102. \
  103. case FP_CLS_ZERO: \
  104. X##_e = 0; \
  105. _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
  106. break; \
  107. \
  108. case FP_CLS_INF: \
  109. X##_e = _FP_EXPMAX_##fs; \
  110. _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
  111. break; \
  112. \
  113. case FP_CLS_NAN: \
  114. X##_e = _FP_EXPMAX_##fs; \
  115. if (!_FP_KEEPNANFRACP) \
  116. { \
  117. _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
  118. X##_s = 0; \
  119. } \
  120. else \
  121. _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs; \
  122. break; \
  123. } \
  124. __ret; \
  125. })
  126. /*
  127. * Main addition routine. The input values should be cooked.
  128. */
  129. #define _FP_ADD(fs, wc, R, X, Y) \
  130. do { \
  131. switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
  132. { \
  133. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
  134. { \
  135. /* shift the smaller number so that its exponent matches the larger */ \
  136. _FP_I_TYPE diff = X##_e - Y##_e; \
  137. \
  138. if (diff < 0) \
  139. { \
  140. diff = -diff; \
  141. if (diff <= _FP_WFRACBITS_##fs) \
  142. _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs); \
  143. else if (!_FP_FRAC_ZEROP_##wc(X)) \
  144. _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
  145. else \
  146. _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
  147. R##_e = Y##_e; \
  148. } \
  149. else \
  150. { \
  151. if (diff > 0) \
  152. { \
  153. if (diff <= _FP_WFRACBITS_##fs) \
  154. _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs); \
  155. else if (!_FP_FRAC_ZEROP_##wc(Y)) \
  156. _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
  157. else \
  158. _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc); \
  159. } \
  160. R##_e = X##_e; \
  161. } \
  162. \
  163. R##_c = FP_CLS_NORMAL; \
  164. \
  165. if (X##_s == Y##_s) \
  166. { \
  167. R##_s = X##_s; \
  168. _FP_FRAC_ADD_##wc(R, X, Y); \
  169. if (_FP_FRAC_OVERP_##wc(fs, R)) \
  170. { \
  171. _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
  172. R##_e++; \
  173. } \
  174. } \
  175. else \
  176. { \
  177. R##_s = X##_s; \
  178. _FP_FRAC_SUB_##wc(R, X, Y); \
  179. if (_FP_FRAC_ZEROP_##wc(R)) \
  180. { \
  181. /* return an exact zero */ \
  182. if (FP_ROUNDMODE == FP_RND_MINF) \
  183. R##_s |= Y##_s; \
  184. else \
  185. R##_s &= Y##_s; \
  186. R##_c = FP_CLS_ZERO; \
  187. } \
  188. else \
  189. { \
  190. if (_FP_FRAC_NEGP_##wc(R)) \
  191. { \
  192. _FP_FRAC_SUB_##wc(R, Y, X); \
  193. R##_s = Y##_s; \
  194. } \
  195. \
  196. /* renormalize after subtraction */ \
  197. _FP_FRAC_CLZ_##wc(diff, R); \
  198. diff -= _FP_WFRACXBITS_##fs; \
  199. if (diff) \
  200. { \
  201. R##_e -= diff; \
  202. _FP_FRAC_SLL_##wc(R, diff); \
  203. } \
  204. } \
  205. } \
  206. break; \
  207. } \
  208. \
  209. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
  210. _FP_CHOOSENAN(fs, wc, R, X, Y); \
  211. break; \
  212. \
  213. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
  214. R##_e = X##_e; \
  215. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
  216. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
  217. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
  218. _FP_FRAC_COPY_##wc(R, X); \
  219. R##_s = X##_s; \
  220. R##_c = X##_c; \
  221. break; \
  222. \
  223. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
  224. R##_e = Y##_e; \
  225. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
  226. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
  227. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
  228. _FP_FRAC_COPY_##wc(R, Y); \
  229. R##_s = Y##_s; \
  230. R##_c = Y##_c; \
  231. break; \
  232. \
  233. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
  234. if (X##_s != Y##_s) \
  235. { \
  236. /* +INF + -INF => NAN */ \
  237. _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
  238. R##_s = X##_s ^ Y##_s; \
  239. R##_c = FP_CLS_NAN; \
  240. break; \
  241. } \
  242. /* FALLTHRU */ \
  243. \
  244. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
  245. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
  246. R##_s = X##_s; \
  247. R##_c = FP_CLS_INF; \
  248. break; \
  249. \
  250. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
  251. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
  252. R##_s = Y##_s; \
  253. R##_c = FP_CLS_INF; \
  254. break; \
  255. \
  256. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
  257. /* make sure the sign is correct */ \
  258. if (FP_ROUNDMODE == FP_RND_MINF) \
  259. R##_s = X##_s | Y##_s; \
  260. else \
  261. R##_s = X##_s & Y##_s; \
  262. R##_c = FP_CLS_ZERO; \
  263. break; \
  264. \
  265. default: \
  266. abort(); \
  267. } \
  268. } while (0)
  269. /*
  270. * Main negation routine. FIXME -- when we care about setting exception
  271. * bits reliably, this will not do. We should examine all of the fp classes.
  272. */
  273. #define _FP_NEG(fs, wc, R, X) \
  274. do { \
  275. _FP_FRAC_COPY_##wc(R, X); \
  276. R##_c = X##_c; \
  277. R##_e = X##_e; \
  278. R##_s = 1 ^ X##_s; \
  279. } while (0)
  280. /*
  281. * Main multiplication routine. The input values should be cooked.
  282. */
  283. #define _FP_MUL(fs, wc, R, X, Y) \
  284. do { \
  285. R##_s = X##_s ^ Y##_s; \
  286. switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
  287. { \
  288. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
  289. R##_c = FP_CLS_NORMAL; \
  290. R##_e = X##_e + Y##_e + 1; \
  291. \
  292. _FP_MUL_MEAT_##fs(R,X,Y); \
  293. \
  294. if (_FP_FRAC_OVERP_##wc(fs, R)) \
  295. _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
  296. else \
  297. R##_e--; \
  298. break; \
  299. \
  300. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
  301. _FP_CHOOSENAN(fs, wc, R, X, Y); \
  302. break; \
  303. \
  304. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
  305. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
  306. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
  307. R##_s = X##_s; \
  308. \
  309. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
  310. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
  311. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
  312. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
  313. _FP_FRAC_COPY_##wc(R, X); \
  314. R##_c = X##_c; \
  315. break; \
  316. \
  317. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
  318. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
  319. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
  320. R##_s = Y##_s; \
  321. \
  322. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
  323. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
  324. _FP_FRAC_COPY_##wc(R, Y); \
  325. R##_c = Y##_c; \
  326. break; \
  327. \
  328. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
  329. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
  330. R##_c = FP_CLS_NAN; \
  331. _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
  332. break; \
  333. \
  334. default: \
  335. abort(); \
  336. } \
  337. } while (0)
  338. /*
  339. * Main division routine. The input values should be cooked.
  340. */
  341. #define _FP_DIV(fs, wc, R, X, Y) \
  342. do { \
  343. R##_s = X##_s ^ Y##_s; \
  344. switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
  345. { \
  346. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
  347. R##_c = FP_CLS_NORMAL; \
  348. R##_e = X##_e - Y##_e; \
  349. \
  350. _FP_DIV_MEAT_##fs(R,X,Y); \
  351. break; \
  352. \
  353. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
  354. _FP_CHOOSENAN(fs, wc, R, X, Y); \
  355. break; \
  356. \
  357. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
  358. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
  359. case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
  360. R##_s = X##_s; \
  361. _FP_FRAC_COPY_##wc(R, X); \
  362. R##_c = X##_c; \
  363. break; \
  364. \
  365. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
  366. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
  367. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
  368. R##_s = Y##_s; \
  369. _FP_FRAC_COPY_##wc(R, Y); \
  370. R##_c = Y##_c; \
  371. break; \
  372. \
  373. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
  374. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
  375. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
  376. R##_c = FP_CLS_ZERO; \
  377. break; \
  378. \
  379. case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
  380. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
  381. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
  382. R##_c = FP_CLS_INF; \
  383. break; \
  384. \
  385. case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
  386. case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
  387. R##_c = FP_CLS_NAN; \
  388. _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
  389. break; \
  390. \
  391. default: \
  392. abort(); \
  393. } \
  394. } while (0)
  395. /*
  396. * Main differential comparison routine. The inputs should be raw not
  397. * cooked. The return is -1,0,1 for normal values, 2 otherwise.
  398. */
  399. #define _FP_CMP(fs, wc, ret, X, Y, un) \
  400. do { \
  401. /* NANs are unordered */ \
  402. if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
  403. || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
  404. { \
  405. ret = un; \
  406. } \
  407. else \
  408. { \
  409. int __x_zero = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
  410. int __y_zero = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
  411. \
  412. if (__x_zero && __y_zero) \
  413. ret = 0; \
  414. else if (__x_zero) \
  415. ret = Y##_s ? 1 : -1; \
  416. else if (__y_zero) \
  417. ret = X##_s ? -1 : 1; \
  418. else if (X##_s != Y##_s) \
  419. ret = X##_s ? -1 : 1; \
  420. else if (X##_e > Y##_e) \
  421. ret = X##_s ? -1 : 1; \
  422. else if (X##_e < Y##_e) \
  423. ret = X##_s ? 1 : -1; \
  424. else if (_FP_FRAC_GT_##wc(X, Y)) \
  425. ret = X##_s ? -1 : 1; \
  426. else if (_FP_FRAC_GT_##wc(Y, X)) \
  427. ret = X##_s ? 1 : -1; \
  428. else \
  429. ret = 0; \
  430. } \
  431. } while (0)
  432. /* Simplification for strict equality. */
  433. #define _FP_CMP_EQ(fs, wc, ret, X, Y) \
  434. do { \
  435. /* NANs are unordered */ \
  436. if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
  437. || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
  438. { \
  439. ret = 1; \
  440. } \
  441. else \
  442. { \
  443. ret = !(X##_e == Y##_e \
  444. && _FP_FRAC_EQ_##wc(X, Y) \
  445. && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
  446. } \
  447. } while (0)
  448. /*
  449. * Main square root routine. The input value should be cooked.
  450. */
  451. #define _FP_SQRT(fs, wc, R, X) \
  452. do { \
  453. _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
  454. _FP_W_TYPE q; \
  455. switch (X##_c) \
  456. { \
  457. case FP_CLS_NAN: \
  458. R##_s = 0; \
  459. R##_c = FP_CLS_NAN; \
  460. _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
  461. break; \
  462. case FP_CLS_INF: \
  463. if (X##_s) \
  464. { \
  465. R##_s = 0; \
  466. R##_c = FP_CLS_NAN; /* sNAN */ \
  467. } \
  468. else \
  469. { \
  470. R##_s = 0; \
  471. R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
  472. } \
  473. break; \
  474. case FP_CLS_ZERO: \
  475. R##_s = X##_s; \
  476. R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
  477. break; \
  478. case FP_CLS_NORMAL: \
  479. R##_s = 0; \
  480. if (X##_s) \
  481. { \
  482. R##_c = FP_CLS_NAN; /* sNAN */ \
  483. break; \
  484. } \
  485. R##_c = FP_CLS_NORMAL; \
  486. if (X##_e & 1) \
  487. _FP_FRAC_SLL_##wc(X, 1); \
  488. R##_e = X##_e >> 1; \
  489. _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
  490. _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
  491. q = _FP_OVERFLOW_##fs; \
  492. _FP_FRAC_SLL_##wc(X, 1); \
  493. _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
  494. _FP_FRAC_SRL_##wc(R, 1); \
  495. } \
  496. } while (0)
  497. /*
  498. * Convert from FP to integer
  499. */
  500. /* "When a NaN, infinity, large positive argument >= 2147483648.0, or
  501. * large negative argument <= -2147483649.0 is converted to an integer,
  502. * the invalid_current bit...should be set and fp_exception_IEEE_754 should
  503. * be raised. If the floating point invalid trap is disabled, no trap occurs
  504. * and a numerical result is generated: if the sign bit of the operand
  505. * is 0, the result is 2147483647; if the sign bit of the operand is 1,
  506. * the result is -2147483648."
  507. * Similarly for conversion to extended ints, except that the boundaries
  508. * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and
  509. * -2^63 for s=1.
  510. * -- SPARC Architecture Manual V9, Appendix B, which specifies how
  511. * SPARCs resolve implementation dependencies in the IEEE-754 spec.
  512. * I don't believe that the code below follows this. I'm not even sure
  513. * it's right!
  514. * It doesn't cope with needing to convert to an n bit integer when there
  515. * is no n bit integer type. Fortunately gcc provides long long so this
  516. * isn't a problem for sparc32.
  517. * I have, however, fixed its NaN handling to conform as above.
  518. * -- PMM 02/1998
  519. * NB: rsigned is not 'is r declared signed?' but 'should the value stored
  520. * in r be signed or unsigned?'. r is always(?) declared unsigned.
  521. * Comments below are mine, BTW -- PMM
  522. */
  523. #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
  524. do { \
  525. switch (X##_c) \
  526. { \
  527. case FP_CLS_NORMAL: \
  528. if (X##_e < 0) \
  529. { \
  530. /* case FP_CLS_NAN: see above! */ \
  531. case FP_CLS_ZERO: \
  532. r = 0; \
  533. } \
  534. else if (X##_e >= rsize - (rsigned != 0)) \
  535. { /* overflow */ \
  536. case FP_CLS_NAN: \
  537. case FP_CLS_INF: \
  538. if (rsigned) \
  539. { \
  540. r = 1; \
  541. r <<= rsize - 1; \
  542. r -= 1 - X##_s; \
  543. } \
  544. else \
  545. { \
  546. r = 0; \
  547. if (!X##_s) \
  548. r = ~r; \
  549. } \
  550. } \
  551. else \
  552. { \
  553. if (_FP_W_TYPE_SIZE*wc < rsize) \
  554. { \
  555. _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
  556. r <<= X##_e - _FP_WFRACBITS_##fs; \
  557. } \
  558. else \
  559. { \
  560. if (X##_e >= _FP_WFRACBITS_##fs) \
  561. _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));\
  562. else \
  563. _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));\
  564. _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
  565. } \
  566. if (rsigned && X##_s) \
  567. r = -r; \
  568. } \
  569. break; \
  570. } \
  571. } while (0)
  572. #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
  573. do { \
  574. if (r) \
  575. { \
  576. X##_c = FP_CLS_NORMAL; \
  577. \
  578. if ((X##_s = (r < 0))) \
  579. r = -r; \
  580. /* Note that `r' is now considered unsigned, so we don't have \
  581. to worry about the single signed overflow case. */ \
  582. \
  583. if (rsize <= _FP_W_TYPE_SIZE) \
  584. __FP_CLZ(X##_e, r); \
  585. else \
  586. __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), \
  587. (_FP_W_TYPE)r); \
  588. if (rsize < _FP_W_TYPE_SIZE) \
  589. X##_e -= (_FP_W_TYPE_SIZE - rsize); \
  590. X##_e = rsize - X##_e - 1; \
  591. \
  592. if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \
  593. __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize); \
  594. r &= ~((_FP_W_TYPE)1 << X##_e); \
  595. _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize); \
  596. _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
  597. } \
  598. else \
  599. { \
  600. X##_c = FP_CLS_ZERO, X##_s = 0; \
  601. } \
  602. } while (0)
  603. #define FP_CONV(dfs,sfs,dwc,swc,D,S) \
  604. do { \
  605. _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S); \
  606. D##_e = S##_e; \
  607. D##_c = S##_c; \
  608. D##_s = S##_s; \
  609. } while (0)
  610. /*
  611. * Helper primitives.
  612. */
  613. /* Count leading zeros in a word. */
  614. #ifndef __FP_CLZ
  615. #if _FP_W_TYPE_SIZE < 64
  616. /* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
  617. #define __FP_CLZ(r, x) \
  618. do { \
  619. _FP_W_TYPE _t = (x); \
  620. r = _FP_W_TYPE_SIZE - 1; \
  621. if (_t > 0xffff) r -= 16; \
  622. if (_t > 0xffff) _t >>= 16; \
  623. if (_t > 0xff) r -= 8; \
  624. if (_t > 0xff) _t >>= 8; \
  625. if (_t & 0xf0) r -= 4; \
  626. if (_t & 0xf0) _t >>= 4; \
  627. if (_t & 0xc) r -= 2; \
  628. if (_t & 0xc) _t >>= 2; \
  629. if (_t & 0x2) r -= 1; \
  630. } while (0)
  631. #else /* not _FP_W_TYPE_SIZE < 64 */
  632. #define __FP_CLZ(r, x) \
  633. do { \
  634. _FP_W_TYPE _t = (x); \
  635. r = _FP_W_TYPE_SIZE - 1; \
  636. if (_t > 0xffffffff) r -= 32; \
  637. if (_t > 0xffffffff) _t >>= 32; \
  638. if (_t > 0xffff) r -= 16; \
  639. if (_t > 0xffff) _t >>= 16; \
  640. if (_t > 0xff) r -= 8; \
  641. if (_t > 0xff) _t >>= 8; \
  642. if (_t & 0xf0) r -= 4; \
  643. if (_t & 0xf0) _t >>= 4; \
  644. if (_t & 0xc) r -= 2; \
  645. if (_t & 0xc) _t >>= 2; \
  646. if (_t & 0x2) r -= 1; \
  647. } while (0)
  648. #endif /* not _FP_W_TYPE_SIZE < 64 */
  649. #endif /* ndef __FP_CLZ */
  650. #define _FP_DIV_HELP_imm(q, r, n, d) \
  651. do { \
  652. q = n / d, r = n % d; \
  653. } while (0)