extended.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /* Software floating-point emulation.
  2. Definitions for IEEE Extended Precision.
  3. Copyright (C) 1999 Free Software Foundation, Inc.
  4. This file is part of the GNU C Library.
  5. Contributed by Jakub Jelinek (jj@ultra.linux.cz).
  6. The GNU C Library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Library General Public License as
  8. published by the Free Software Foundation; either version 2 of the
  9. License, or (at your option) any later version.
  10. The GNU C Library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB. If
  16. not, write to the Free Software Foundation, Inc.,
  17. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  18. #ifndef __MATH_EMU_EXTENDED_H__
  19. #define __MATH_EMU_EXTENDED_H__
  20. #if _FP_W_TYPE_SIZE < 32
  21. #error "Here's a nickel, kid. Go buy yourself a real computer."
  22. #endif
  23. #if _FP_W_TYPE_SIZE < 64
  24. #define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE)
  25. #else
  26. #define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE)
  27. #endif
  28. #define _FP_FRACBITS_E 64
  29. #define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E)
  30. #define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E)
  31. #define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E)
  32. #define _FP_EXPBITS_E 15
  33. #define _FP_EXPBIAS_E 16383
  34. #define _FP_EXPMAX_E 32767
  35. #define _FP_QNANBIT_E \
  36. ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
  37. #define _FP_IMPLBIT_E \
  38. ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
  39. #define _FP_OVERFLOW_E \
  40. ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
  41. #if _FP_W_TYPE_SIZE < 64
  42. union _FP_UNION_E
  43. {
  44. long double flt;
  45. struct
  46. {
  47. #if __BYTE_ORDER == __BIG_ENDIAN
  48. unsigned long pad1 : _FP_W_TYPE_SIZE;
  49. unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
  50. unsigned long sign : 1;
  51. unsigned long exp : _FP_EXPBITS_E;
  52. unsigned long frac1 : _FP_W_TYPE_SIZE;
  53. unsigned long frac0 : _FP_W_TYPE_SIZE;
  54. #else
  55. unsigned long frac0 : _FP_W_TYPE_SIZE;
  56. unsigned long frac1 : _FP_W_TYPE_SIZE;
  57. unsigned exp : _FP_EXPBITS_E;
  58. unsigned sign : 1;
  59. #endif /* not bigendian */
  60. } bits __attribute__((packed));
  61. };
  62. #define FP_DECL_E(X) _FP_DECL(4,X)
  63. #define FP_UNPACK_RAW_E(X, val) \
  64. do { \
  65. union _FP_UNION_E _flo; _flo.flt = (val); \
  66. \
  67. X##_f[2] = 0; X##_f[3] = 0; \
  68. X##_f[0] = _flo.bits.frac0; \
  69. X##_f[1] = _flo.bits.frac1; \
  70. X##_e = _flo.bits.exp; \
  71. X##_s = _flo.bits.sign; \
  72. if (!X##_e && (X##_f[1] || X##_f[0]) \
  73. && !(X##_f[1] & _FP_IMPLBIT_E)) \
  74. { \
  75. X##_e++; \
  76. FP_SET_EXCEPTION(FP_EX_DENORM); \
  77. } \
  78. } while (0)
  79. #define FP_UNPACK_RAW_EP(X, val) \
  80. do { \
  81. union _FP_UNION_E *_flo = \
  82. (union _FP_UNION_E *)(val); \
  83. \
  84. X##_f[2] = 0; X##_f[3] = 0; \
  85. X##_f[0] = _flo->bits.frac0; \
  86. X##_f[1] = _flo->bits.frac1; \
  87. X##_e = _flo->bits.exp; \
  88. X##_s = _flo->bits.sign; \
  89. if (!X##_e && (X##_f[1] || X##_f[0]) \
  90. && !(X##_f[1] & _FP_IMPLBIT_E)) \
  91. { \
  92. X##_e++; \
  93. FP_SET_EXCEPTION(FP_EX_DENORM); \
  94. } \
  95. } while (0)
  96. #define FP_PACK_RAW_E(val, X) \
  97. do { \
  98. union _FP_UNION_E _flo; \
  99. \
  100. if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \
  101. else X##_f[1] &= ~(_FP_IMPLBIT_E); \
  102. _flo.bits.frac0 = X##_f[0]; \
  103. _flo.bits.frac1 = X##_f[1]; \
  104. _flo.bits.exp = X##_e; \
  105. _flo.bits.sign = X##_s; \
  106. \
  107. (val) = _flo.flt; \
  108. } while (0)
  109. #define FP_PACK_RAW_EP(val, X) \
  110. do { \
  111. if (!FP_INHIBIT_RESULTS) \
  112. { \
  113. union _FP_UNION_E *_flo = \
  114. (union _FP_UNION_E *)(val); \
  115. \
  116. if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \
  117. else X##_f[1] &= ~(_FP_IMPLBIT_E); \
  118. _flo->bits.frac0 = X##_f[0]; \
  119. _flo->bits.frac1 = X##_f[1]; \
  120. _flo->bits.exp = X##_e; \
  121. _flo->bits.sign = X##_s; \
  122. } \
  123. } while (0)
  124. #define FP_UNPACK_E(X,val) \
  125. do { \
  126. FP_UNPACK_RAW_E(X,val); \
  127. _FP_UNPACK_CANONICAL(E,4,X); \
  128. } while (0)
  129. #define FP_UNPACK_EP(X,val) \
  130. do { \
  131. FP_UNPACK_RAW_2_P(X,val); \
  132. _FP_UNPACK_CANONICAL(E,4,X); \
  133. } while (0)
  134. #define FP_PACK_E(val,X) \
  135. do { \
  136. _FP_PACK_CANONICAL(E,4,X); \
  137. FP_PACK_RAW_E(val,X); \
  138. } while (0)
  139. #define FP_PACK_EP(val,X) \
  140. do { \
  141. _FP_PACK_CANONICAL(E,4,X); \
  142. FP_PACK_RAW_EP(val,X); \
  143. } while (0)
  144. #define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X)
  145. #define FP_NEG_E(R,X) _FP_NEG(E,4,R,X)
  146. #define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y)
  147. #define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y)
  148. #define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y)
  149. #define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y)
  150. #define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X)
  151. /*
  152. * Square root algorithms:
  153. * We have just one right now, maybe Newton approximation
  154. * should be added for those machines where division is fast.
  155. * This has special _E version because standard _4 square
  156. * root would not work (it has to start normally with the
  157. * second word and not the first), but as we have to do it
  158. * anyway, we optimize it by doing most of the calculations
  159. * in two UWtype registers instead of four.
  160. */
  161. #define _FP_SQRT_MEAT_E(R, S, T, X, q) \
  162. do { \
  163. q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
  164. _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \
  165. while (q) \
  166. { \
  167. T##_f[1] = S##_f[1] + q; \
  168. if (T##_f[1] <= X##_f[1]) \
  169. { \
  170. S##_f[1] = T##_f[1] + q; \
  171. X##_f[1] -= T##_f[1]; \
  172. R##_f[1] += q; \
  173. } \
  174. _FP_FRAC_SLL_2(X, 1); \
  175. q >>= 1; \
  176. } \
  177. q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
  178. while (q) \
  179. { \
  180. T##_f[0] = S##_f[0] + q; \
  181. T##_f[1] = S##_f[1]; \
  182. if (T##_f[1] < X##_f[1] || \
  183. (T##_f[1] == X##_f[1] && \
  184. T##_f[0] <= X##_f[0])) \
  185. { \
  186. S##_f[0] = T##_f[0] + q; \
  187. S##_f[1] += (T##_f[0] > S##_f[0]); \
  188. _FP_FRAC_DEC_2(X, T); \
  189. R##_f[0] += q; \
  190. } \
  191. _FP_FRAC_SLL_2(X, 1); \
  192. q >>= 1; \
  193. } \
  194. _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \
  195. if (X##_f[0] | X##_f[1]) \
  196. { \
  197. if (S##_f[1] < X##_f[1] || \
  198. (S##_f[1] == X##_f[1] && \
  199. S##_f[0] < X##_f[0])) \
  200. R##_f[0] |= _FP_WORK_ROUND; \
  201. R##_f[0] |= _FP_WORK_STICKY; \
  202. } \
  203. } while (0)
  204. #define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un)
  205. #define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y)
  206. #define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg)
  207. #define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,4,r,X,rsz,rsg)
  208. #define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt)
  209. #define _FP_FRAC_HIGH_E(X) (X##_f[2])
  210. #define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1])
  211. #else /* not _FP_W_TYPE_SIZE < 64 */
  212. union _FP_UNION_E
  213. {
  214. long double flt /* __attribute__((mode(TF))) */ ;
  215. struct {
  216. #if __BYTE_ORDER == __BIG_ENDIAN
  217. unsigned long pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
  218. unsigned sign : 1;
  219. unsigned exp : _FP_EXPBITS_E;
  220. unsigned long frac : _FP_W_TYPE_SIZE;
  221. #else
  222. unsigned long frac : _FP_W_TYPE_SIZE;
  223. unsigned exp : _FP_EXPBITS_E;
  224. unsigned sign : 1;
  225. #endif
  226. } bits;
  227. };
  228. #define FP_DECL_E(X) _FP_DECL(2,X)
  229. #define FP_UNPACK_RAW_E(X, val) \
  230. do { \
  231. union _FP_UNION_E _flo; _flo.flt = (val); \
  232. \
  233. X##_f0 = _flo.bits.frac; \
  234. X##_f1 = 0; \
  235. X##_e = _flo.bits.exp; \
  236. X##_s = _flo.bits.sign; \
  237. if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \
  238. { \
  239. X##_e++; \
  240. FP_SET_EXCEPTION(FP_EX_DENORM); \
  241. } \
  242. } while (0)
  243. #define FP_UNPACK_RAW_EP(X, val) \
  244. do { \
  245. union _FP_UNION_E *_flo = \
  246. (union _FP_UNION_E *)(val); \
  247. \
  248. X##_f0 = _flo->bits.frac; \
  249. X##_f1 = 0; \
  250. X##_e = _flo->bits.exp; \
  251. X##_s = _flo->bits.sign; \
  252. if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \
  253. { \
  254. X##_e++; \
  255. FP_SET_EXCEPTION(FP_EX_DENORM); \
  256. } \
  257. } while (0)
  258. #define FP_PACK_RAW_E(val, X) \
  259. do { \
  260. union _FP_UNION_E _flo; \
  261. \
  262. if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \
  263. else X##_f0 &= ~(_FP_IMPLBIT_E); \
  264. _flo.bits.frac = X##_f0; \
  265. _flo.bits.exp = X##_e; \
  266. _flo.bits.sign = X##_s; \
  267. \
  268. (val) = _flo.flt; \
  269. } while (0)
  270. #define FP_PACK_RAW_EP(fs, val, X) \
  271. do { \
  272. if (!FP_INHIBIT_RESULTS) \
  273. { \
  274. union _FP_UNION_E *_flo = \
  275. (union _FP_UNION_E *)(val); \
  276. \
  277. if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \
  278. else X##_f0 &= ~(_FP_IMPLBIT_E); \
  279. _flo->bits.frac = X##_f0; \
  280. _flo->bits.exp = X##_e; \
  281. _flo->bits.sign = X##_s; \
  282. } \
  283. } while (0)
  284. #define FP_UNPACK_E(X,val) \
  285. do { \
  286. FP_UNPACK_RAW_E(X,val); \
  287. _FP_UNPACK_CANONICAL(E,2,X); \
  288. } while (0)
  289. #define FP_UNPACK_EP(X,val) \
  290. do { \
  291. FP_UNPACK_RAW_EP(X,val); \
  292. _FP_UNPACK_CANONICAL(E,2,X); \
  293. } while (0)
  294. #define FP_PACK_E(val,X) \
  295. do { \
  296. _FP_PACK_CANONICAL(E,2,X); \
  297. FP_PACK_RAW_E(val,X); \
  298. } while (0)
  299. #define FP_PACK_EP(val,X) \
  300. do { \
  301. _FP_PACK_CANONICAL(E,2,X); \
  302. FP_PACK_RAW_EP(val,X); \
  303. } while (0)
  304. #define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X)
  305. #define FP_NEG_E(R,X) _FP_NEG(E,2,R,X)
  306. #define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y)
  307. #define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y)
  308. #define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y)
  309. #define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y)
  310. #define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X)
  311. /*
  312. * Square root algorithms:
  313. * We have just one right now, maybe Newton approximation
  314. * should be added for those machines where division is fast.
  315. * We optimize it by doing most of the calculations
  316. * in one UWtype registers instead of two, although we don't
  317. * have to.
  318. */
  319. #define _FP_SQRT_MEAT_E(R, S, T, X, q) \
  320. do { \
  321. q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
  322. _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \
  323. while (q) \
  324. { \
  325. T##_f0 = S##_f0 + q; \
  326. if (T##_f0 <= X##_f0) \
  327. { \
  328. S##_f0 = T##_f0 + q; \
  329. X##_f0 -= T##_f0; \
  330. R##_f0 += q; \
  331. } \
  332. _FP_FRAC_SLL_1(X, 1); \
  333. q >>= 1; \
  334. } \
  335. _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \
  336. if (X##_f0) \
  337. { \
  338. if (S##_f0 < X##_f0) \
  339. R##_f0 |= _FP_WORK_ROUND; \
  340. R##_f0 |= _FP_WORK_STICKY; \
  341. } \
  342. } while (0)
  343. #define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un)
  344. #define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y)
  345. #define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg)
  346. #define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,2,r,X,rsz,rsg)
  347. #define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt)
  348. #define _FP_FRAC_HIGH_E(X) (X##_f1)
  349. #define _FP_FRAC_HIGH_RAW_E(X) (X##_f0)
  350. #endif /* not _FP_W_TYPE_SIZE < 64 */
  351. #endif /* __MATH_EMU_EXTENDED_H__ */