polyfill.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. #include <limits.h>
  2. #include <stdint.h>
  3. #include <float.h>
  4. #include <math.h>
  5. #include <string.h>
  6. #define POLYFILL_FUN_1(name, ret, arg1) \
  7. ret name(arg1) {}
  8. #define POLYFILL_FUN_2(name, ret, arg1, arg2) \
  9. ret name(arg1, arg2) {}
  10. #define POLYFILL_FUN_3(name, ret, arg1, arg2, arg3) \
  11. ret name(arg1, arg2, arg3) {}
  12. #define POLYFILL_FUN_4(name, ret, arg1, arg2, arg3, arg4) \
  13. ret name(arg1, arg2, arg3, arg4) {}
  14. #ifndef __aeabi_dcmple
  15. POLYFILL_FUN_2(__aeabi_dcmple, double, double, double)
  16. #endif
  17. #ifndef __aeabi_dcmplt
  18. POLYFILL_FUN_2(__aeabi_dcmplt, double, double, double)
  19. #endif
  20. #ifndef __aeabi_dcmpun
  21. POLYFILL_FUN_2(__aeabi_dcmpun, double, double, double)
  22. #endif
  23. #ifndef __aeabi_dcmpeq
  24. POLYFILL_FUN_2(__aeabi_dcmpeq, double, double, double)
  25. #endif
  26. #ifndef __aeabi_dmul
  27. POLYFILL_FUN_2(__aeabi_dmul, double, double, double)
  28. #endif
  29. #ifndef __aeabi_dadd
  30. POLYFILL_FUN_2(__aeabi_dadd, double, double, double)
  31. #endif
  32. #ifndef __aeabi_ddiv
  33. POLYFILL_FUN_2(__aeabi_ddiv, double, double, double)
  34. #endif
  35. #ifndef __aeabi_l2d
  36. POLYFILL_FUN_1(__aeabi_l2d, double, long)
  37. #endif
  38. #ifndef __aeabi_f2d
  39. POLYFILL_FUN_1(__aeabi_f2d, double, float)
  40. #endif
  41. #ifndef __aeabi_dsub
  42. POLYFILL_FUN_2(__aeabi_dsub, double, double, double)
  43. #endif
  44. #ifndef __aeabi_dcmpge
  45. POLYFILL_FUN_2(__aeabi_dcmpge, double, double, double)
  46. #endif
  47. #ifndef __aeabi_i2d
  48. POLYFILL_FUN_1(__aeabi_i2d, double, long)
  49. #endif
  50. #ifndef __aeabi_dcmpgt
  51. POLYFILL_FUN_1(__aeabi_dcmpgt, double, double)
  52. #endif
  53. #ifndef __aeabi_d2iz
  54. POLYFILL_FUN_1(__aeabi_d2iz, long int, double)
  55. #endif
  56. #ifndef __aeabi_d2lz
  57. POLYFILL_FUN_1(__aeabi_d2lz, long, double)
  58. #endif
  59. #ifndef __aeabi_d2uiz
  60. POLYFILL_FUN_1(__aeabi_d2uiz, unsigned long int, double)
  61. #endif
  62. #ifndef __aeabi_d2f
  63. POLYFILL_FUN_1(__aeabi_d2f, float, double)
  64. #endif
  65. #ifndef __aeabi_ldivmod
  66. POLYFILL_FUN_2(__aeabi_ldivmod, long, long, long)
  67. #endif
  68. #ifndef strtox
  69. POLYFILL_FUN_4(strtox, long long unsigned int, const char *, char **, int, long long unsigned int)
  70. #endif
  71. #if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1
  72. #define EPS DBL_EPSILON
  73. #elif FLT_EVAL_METHOD == 2
  74. #define EPS LDBL_EPSILON
  75. #endif
  76. static const double_t toint = 1 / EPS;
  77. #ifndef FORCE_EVAL
  78. #define FORCE_EVAL(x) \
  79. do \
  80. { \
  81. if (sizeof(x) == sizeof(float)) \
  82. { \
  83. volatile float __x; \
  84. __x = (x); \
  85. (void)__x; \
  86. } \
  87. else if (sizeof(x) == sizeof(double)) \
  88. { \
  89. volatile double __x; \
  90. __x = (x); \
  91. (void)__x; \
  92. } \
  93. else \
  94. { \
  95. volatile long double __x; \
  96. __x = (x); \
  97. (void)__x; \
  98. } \
  99. } while (0)
  100. #endif
  101. #ifndef floorf
  102. float floorf(float x)
  103. {
  104. union
  105. {
  106. float f;
  107. uint32_t i;
  108. } u = {x};
  109. int e = (int)(u.i >> 23 & 0xff) - 0x7f;
  110. uint32_t m;
  111. if (e >= 23)
  112. return x;
  113. if (e >= 0)
  114. {
  115. m = 0x007fffff >> e;
  116. if ((u.i & m) == 0)
  117. return x;
  118. FORCE_EVAL(x + 0x1p120f);
  119. if (u.i >> 31)
  120. u.i += m;
  121. u.i &= ~m;
  122. }
  123. else
  124. {
  125. FORCE_EVAL(x + 0x1p120f);
  126. if (u.i >> 31 == 0)
  127. u.i = 0;
  128. else if (u.i << 1)
  129. u.f = -1.0;
  130. }
  131. return u.f;
  132. }
  133. #endif
  134. #ifndef floor
  135. double floor(double x)
  136. {
  137. union
  138. {
  139. double f;
  140. uint64_t i;
  141. } u = {x};
  142. int e = u.i >> 52 & 0x7ff;
  143. double_t y;
  144. if (e >= 0x3ff + 52 || x == 0)
  145. return x;
  146. /* y = int(x) - x, where int(x) is an integer neighbor of x */
  147. if (u.i >> 63)
  148. y = x - toint + toint - x;
  149. else
  150. y = x + toint - toint - x;
  151. /* special case because of non-nearest rounding modes */
  152. if (e <= 0x3ff - 1)
  153. {
  154. FORCE_EVAL(y);
  155. return u.i >> 63 ? -1 : 0;
  156. }
  157. if (y > 0)
  158. return x + y - 1;
  159. return x + y;
  160. }
  161. #endif
  162. #ifndef fmodf
  163. float fmodf(float x, float y)
  164. {
  165. union
  166. {
  167. float f;
  168. uint32_t i;
  169. } ux = {x}, uy = {y};
  170. int ex = ux.i >> 23 & 0xff;
  171. int ey = uy.i >> 23 & 0xff;
  172. uint32_t sx = ux.i & 0x80000000;
  173. uint32_t i;
  174. uint32_t uxi = ux.i;
  175. if (uy.i << 1 == 0 || isnan(y) || ex == 0xff)
  176. return (x * y) / (x * y);
  177. if (uxi << 1 <= uy.i << 1)
  178. {
  179. if (uxi << 1 == uy.i << 1)
  180. return 0 * x;
  181. return x;
  182. }
  183. /* normalize x and y */
  184. if (!ex)
  185. {
  186. for (i = uxi << 9; i >> 31 == 0; ex--, i <<= 1)
  187. ;
  188. uxi <<= -ex + 1;
  189. }
  190. else
  191. {
  192. uxi &= -1U >> 9;
  193. uxi |= 1U << 23;
  194. }
  195. if (!ey)
  196. {
  197. for (i = uy.i << 9; i >> 31 == 0; ey--, i <<= 1)
  198. ;
  199. uy.i <<= -ey + 1;
  200. }
  201. else
  202. {
  203. uy.i &= -1U >> 9;
  204. uy.i |= 1U << 23;
  205. }
  206. /* x mod y */
  207. for (; ex > ey; ex--)
  208. {
  209. i = uxi - uy.i;
  210. if (i >> 31 == 0)
  211. {
  212. if (i == 0)
  213. return 0 * x;
  214. uxi = i;
  215. }
  216. uxi <<= 1;
  217. }
  218. i = uxi - uy.i;
  219. if (i >> 31 == 0)
  220. {
  221. if (i == 0)
  222. return 0 * x;
  223. uxi = i;
  224. }
  225. for (; uxi >> 23 == 0; uxi <<= 1, ex--)
  226. ;
  227. /* scale result up */
  228. if (ex > 0)
  229. {
  230. uxi -= 1U << 23;
  231. uxi |= (uint32_t)ex << 23;
  232. }
  233. else
  234. {
  235. uxi >>= -ex + 1;
  236. }
  237. uxi |= sx;
  238. ux.i = uxi;
  239. return ux.f;
  240. }
  241. #endif
  242. #ifndef fmod
  243. double fmod(double x, double y)
  244. {
  245. union
  246. {
  247. double f;
  248. uint64_t i;
  249. } ux = {x}, uy = {y};
  250. int ex = ux.i >> 52 & 0x7ff;
  251. int ey = uy.i >> 52 & 0x7ff;
  252. int sx = ux.i >> 63;
  253. uint64_t i;
  254. /* in the followings uxi should be ux.i, but then gcc wrongly adds */
  255. /* float load/store to inner loops ruining performance and code size */
  256. uint64_t uxi = ux.i;
  257. if (uy.i << 1 == 0 || isnan(y) || ex == 0x7ff)
  258. return (x * y) / (x * y);
  259. if (uxi << 1 <= uy.i << 1)
  260. {
  261. if (uxi << 1 == uy.i << 1)
  262. return 0 * x;
  263. return x;
  264. }
  265. /* normalize x and y */
  266. if (!ex)
  267. {
  268. for (i = uxi << 12; i >> 63 == 0; ex--, i <<= 1)
  269. ;
  270. uxi <<= -ex + 1;
  271. }
  272. else
  273. {
  274. uxi &= -1ULL >> 12;
  275. uxi |= 1ULL << 52;
  276. }
  277. if (!ey)
  278. {
  279. for (i = uy.i << 12; i >> 63 == 0; ey--, i <<= 1)
  280. ;
  281. uy.i <<= -ey + 1;
  282. }
  283. else
  284. {
  285. uy.i &= -1ULL >> 12;
  286. uy.i |= 1ULL << 52;
  287. }
  288. /* x mod y */
  289. for (; ex > ey; ex--)
  290. {
  291. i = uxi - uy.i;
  292. if (i >> 63 == 0)
  293. {
  294. if (i == 0)
  295. return 0 * x;
  296. uxi = i;
  297. }
  298. uxi <<= 1;
  299. }
  300. i = uxi - uy.i;
  301. if (i >> 63 == 0)
  302. {
  303. if (i == 0)
  304. return 0 * x;
  305. uxi = i;
  306. }
  307. for (; uxi >> 52 == 0; uxi <<= 1, ex--)
  308. ;
  309. /* scale result */
  310. if (ex > 0)
  311. {
  312. uxi -= 1ULL << 52;
  313. uxi |= (uint64_t)ex << 52;
  314. }
  315. else
  316. {
  317. uxi >>= -ex + 1;
  318. }
  319. uxi |= (uint64_t)sx << 63;
  320. ux.i = uxi;
  321. return ux.f;
  322. }
  323. #endif
  324. #ifndef nearbyintf
  325. float nearbyintf(float x)
  326. {
  327. union
  328. {
  329. float f;
  330. uint32_t i;
  331. } u = {x};
  332. int e = u.i >> 23 & 0xff;
  333. int s = u.i >> 31;
  334. float_t y;
  335. if (e >= 0x7f + 23)
  336. return x;
  337. if (s)
  338. y = x - 0x1p23f + 0x1p23f;
  339. else
  340. y = x + 0x1p23f - 0x1p23f;
  341. if (y == 0)
  342. return s ? -0.0f : 0.0f;
  343. return y;
  344. }
  345. #endif
  346. #ifndef stroll
  347. long long strtoll(const char *restrict s, char **restrict p, int base)
  348. {
  349. return strtox(s, p, base, LLONG_MIN);
  350. }
  351. #endif
  352. #ifndef pow
  353. double pow(double x, double y)
  354. {
  355. return powf(x, y);
  356. }
  357. #endif
  358. #ifndef rint
  359. double rint(double x)
  360. {
  361. union
  362. {
  363. double f;
  364. uint64_t i;
  365. } u = {x};
  366. int e = u.i >> 52 & 0x7ff;
  367. int s = u.i >> 63;
  368. double_t y;
  369. if (e >= 0x3ff + 52)
  370. return x;
  371. if (s)
  372. y = x - toint + toint;
  373. else
  374. y = x + toint - toint;
  375. if (y == 0)
  376. return s ? -0.0 : 0;
  377. return y;
  378. }
  379. #endif
  380. #ifndef nearbyint
  381. double nearbyint(double x)
  382. {
  383. #ifdef FE_INEXACT
  384. #pragma STDC FENV_ACCESS ON
  385. int e;
  386. e = fetestexcept(FE_INEXACT);
  387. #endif
  388. x = rint(x);
  389. #ifdef FE_INEXACT
  390. if (!e)
  391. feclearexcept(FE_INEXACT);
  392. #endif
  393. return x;
  394. }
  395. #endif