pico_double_test.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. //===-- aeabi_cdcmpeq.c - Test __aeabi_cdcmpeq ----------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file tests __aeabi_cdcmpeq for the compiler_rt library.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include <stdint.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <math.h>
  17. #include <pico/double.h>
  18. #include "pico/stdlib.h"
  19. #include "inttypes.h"
  20. extern int __aeabi_dcmpun(double a, double b);
  21. #if __arm__
  22. #include "call_apsr.h"
  23. extern __attribute__((pcs("aapcs"))) void __aeabi_cdcmpeq(double a, double b);
  24. int test__aeabi_cdcmpeq(double a, double b, int expected) {
  25. uint32_t cpsr_value = call_apsr_d(a, b, __aeabi_cdcmpeq);
  26. union cpsr cpsr = {.value = cpsr_value};
  27. if (expected != cpsr.flags.z) {
  28. printf("error in __aeabi_cdcmpeq(%f, %f) => Z = %08x, expected %08x\n",
  29. a, b, cpsr.flags.z, expected);
  30. return 1;
  31. }
  32. return 0;
  33. }
  34. #endif
  35. int test_cdcmpeq() {
  36. #if __arm__
  37. if (test__aeabi_cdcmpeq(1.0, 1.0, 1))
  38. return 1;
  39. if (test__aeabi_cdcmpeq(1234.567, 765.4321, 0))
  40. return 1;
  41. if (test__aeabi_cdcmpeq(-123.0, -678.0, 0))
  42. return 1;
  43. if (test__aeabi_cdcmpeq(0.0, -0.0, 1))
  44. return 1;
  45. if (test__aeabi_cdcmpeq(0.0, 0.0, 1))
  46. return 1;
  47. if (test__aeabi_cdcmpeq(-0.0, -0.0, 1))
  48. return 1;
  49. if (test__aeabi_cdcmpeq(-0.0, 0.0, 1))
  50. return 1;
  51. if (test__aeabi_cdcmpeq(0.0, -1.0, 0))
  52. return 1;
  53. if (test__aeabi_cdcmpeq(-0.0, -1.0, 0))
  54. return 1;
  55. if (test__aeabi_cdcmpeq(-1.0, 0.0, 0))
  56. return 1;
  57. if (test__aeabi_cdcmpeq(-1.0, -0.0, 0))
  58. return 1;
  59. if (test__aeabi_cdcmpeq(1.0, NAN, 0))
  60. return 1;
  61. if (test__aeabi_cdcmpeq(NAN, 1.0, 0))
  62. return 1;
  63. if (test__aeabi_cdcmpeq(NAN, NAN, 0))
  64. return 1;
  65. if (test__aeabi_cdcmpeq(INFINITY, 1.0, 0))
  66. return 1;
  67. if (test__aeabi_cdcmpeq(0.0, INFINITY, 0))
  68. return 1;
  69. if (test__aeabi_cdcmpeq(-INFINITY, 0.0, 0))
  70. return 1;
  71. if (test__aeabi_cdcmpeq(0.0, -INFINITY, 0))
  72. return 1;
  73. if (test__aeabi_cdcmpeq(INFINITY, INFINITY, 1))
  74. return 1;
  75. if (test__aeabi_cdcmpeq(-INFINITY, -INFINITY, 1))
  76. return 1;
  77. #else
  78. printf("skipped\n");
  79. #endif
  80. return 0;
  81. }
  82. #if __arm__
  83. extern __attribute__((pcs("aapcs"))) void __aeabi_cdcmple(double a, double b);
  84. extern __attribute__((pcs("aapcs"))) void __aeabi_cdrcmple(double a, double b);
  85. int test_dcmple_gt(double a, double b, int expected) {
  86. if ((a <= b) != expected) {
  87. printf("error in dcmple(%f, %f) => %d, expected %d\n",
  88. a, b, a <= b, expected);
  89. return 1;
  90. }
  91. if ((a > b) == expected && !isnan(a) && !isnan(b)) {
  92. printf("error in dcmpgt(%f, %f) => %d, expected %d\n",
  93. a, b, a > b, !expected);
  94. return 1;
  95. }
  96. return 0;
  97. }
  98. int test_dcmplt_ge(double a, double b, int expected) {
  99. if ((a < b) != expected) {
  100. printf("error in dcmplt(%f, %f) => %d, expected %d\n",
  101. a, b, a < b, expected);
  102. return 1;
  103. }
  104. if ((a >= b) == expected && !isnan(a) && !isnan(b)) {
  105. printf("error in dcmpge(%f, %f) => %d, expected %d\n",
  106. a, b, a >= b, !expected);
  107. return 1;
  108. }
  109. return 0;
  110. }
  111. int test__aeabi_cdcmple(double a, double b, int expected) {
  112. int32_t cpsr_value = call_apsr_d(a, b, __aeabi_cdcmple);
  113. int32_t r_cpsr_value = call_apsr_d(b, a, __aeabi_cdrcmple);
  114. int32_t cpsr_value2 = call_apsr_d(b, a, __aeabi_cdcmple);
  115. int32_t r_cpsr_value2 = call_apsr_d(a, b, __aeabi_cdrcmple);
  116. if (cpsr_value != r_cpsr_value) {
  117. printf("error: __aeabi_cdcmple(%f, %f) != __aeabi_cdrcmple(%f, %f)\n", a, b, b, a);
  118. return 1;
  119. }
  120. int expected_z, expected_c;
  121. if (expected == -1) {
  122. expected_z = 0;
  123. expected_c = 0;
  124. } else if (expected == 0) {
  125. expected_z = 1;
  126. expected_c = 1;
  127. } else {
  128. // a or b is NaN, or a > b
  129. expected_z = 0;
  130. expected_c = 1;
  131. }
  132. #if PICO_DOUBLE_COMPILER
  133. // gcc has this backwards it seems - not a good thing, but I guess it doesn't ever call them
  134. expected_c ^= 1;
  135. #endif
  136. union cpsr cpsr = {.value = cpsr_value};
  137. if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
  138. printf("error in __aeabi_cdcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
  139. a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
  140. return 1;
  141. }
  142. cpsr.value = r_cpsr_value;
  143. if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
  144. printf("error in __aeabi_cfrcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
  145. a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
  146. return 1;
  147. }
  148. return 0;
  149. }
  150. #endif
  151. int test_cdcmple() {
  152. #if __arm__
  153. if (test__aeabi_cdcmple(1.0, 1.0, 0))
  154. return 1;
  155. if (test__aeabi_cdcmple(1234.567, 765.4321, 1))
  156. return 1;
  157. if (test__aeabi_cdcmple(765.4321, 1234.567, -1))
  158. return 1;
  159. if (test__aeabi_cdcmple(-123.0, -678.0, 1))
  160. return 1;
  161. if (test__aeabi_cdcmple(-678.0, -123.0, -1))
  162. return 1;
  163. if (test__aeabi_cdcmple(-123.0, 678.0, -1))
  164. return 1;
  165. if (test__aeabi_cdcmple(678.0, -123.0, 1))
  166. return 1;
  167. if (test__aeabi_cdcmple(0.0, -0.0, 0))
  168. return 1;
  169. if (test__aeabi_cdcmple(1.0, NAN, 1))
  170. return 1;
  171. if (test__aeabi_cdcmple(NAN, 1.0, 1))
  172. return 1;
  173. if (test__aeabi_cdcmple(NAN, NAN, 1))
  174. return 1;
  175. #else
  176. printf("skipped\n");
  177. #endif
  178. return 0;
  179. }
  180. int test_cmple_gt() {
  181. if (test_dcmple_gt(1.0, 1.0, 1))
  182. return 1;
  183. if (test_dcmple_gt(1234.567, 765.4321, 0))
  184. return 1;
  185. if (test_dcmple_gt(765.4321, 1234.567, 1))
  186. return 1;
  187. if (test_dcmple_gt(-123.0, -678.0, 0))
  188. return 1;
  189. if (test_dcmple_gt(-678.0, -123.0, 1))
  190. return 1;
  191. if (test_dcmple_gt(-123.0, 678.0, 1))
  192. return 1;
  193. if (test_dcmple_gt(678.0, -123.0, 0))
  194. return 1;
  195. if (test_dcmple_gt(0.0, -0.0, 1))
  196. return 1;
  197. if (test_dcmple_gt(-0.0, 0.0, 1))
  198. return 1;
  199. if (test_dcmple_gt(1.0, NAN, 0))
  200. return 1;
  201. if (test_dcmple_gt(NAN, 1.0, 0))
  202. return 1;
  203. if (test_dcmple_gt(NAN, NAN, 0))
  204. return 1;
  205. return 0;
  206. }
  207. int test_cmplt_ge() {
  208. if (test_dcmplt_ge(1.0, 1.0, 0))
  209. return 1;
  210. if (test_dcmplt_ge(1234.567, 765.4321, 0))
  211. return 1;
  212. if (test_dcmplt_ge(765.4321, 1234.567, 1))
  213. return 1;
  214. if (test_dcmplt_ge(-123.0, -678.0, 0))
  215. return 1;
  216. if (test_dcmplt_ge(-678.0, -123.0, 1))
  217. return 1;
  218. if (test_dcmplt_ge(-123.0, 678.0, 1))
  219. return 1;
  220. if (test_dcmplt_ge(678.0, -123.0, 0))
  221. return 1;
  222. if (test_dcmplt_ge(0.0, -0.0, 0))
  223. return 1;
  224. if (test_dcmplt_ge(-0.0, 0.0, 0))
  225. return 1;
  226. if (test_dcmplt_ge(1.0, NAN, 0))
  227. return 1;
  228. if (test_dcmplt_ge(NAN, 1.0, 0))
  229. return 1;
  230. if (test_dcmplt_ge(NAN, NAN, 0))
  231. return 1;
  232. return 0;
  233. }
  234. int check_dcmpun(double a, double b, bool expected, bool expect_equal) {
  235. if (__aeabi_dcmpun(a, b) != expected) {
  236. printf("Failed dcmpun(%f, %f)\n", a, b);
  237. return 1;
  238. }
  239. if ((a == b) != expect_equal) {
  240. printf("Failed equality check %f %f\n", a, b);
  241. __breakpoint();
  242. if (b == a) {
  243. printf("SAS\n");
  244. }
  245. return 1;
  246. }
  247. return 0;
  248. }
  249. int test_dcmpun() {
  250. if (check_dcmpun(0, 0, false, true) ||
  251. check_dcmpun(-INFINITY, INFINITY, false, false) ||
  252. check_dcmpun(NAN, 0, true, false) ||
  253. check_dcmpun(0, NAN, true, false) ||
  254. check_dcmpun(NAN, NAN, true, false) ||
  255. check_dcmpun(-NAN, NAN, true, false)) {
  256. return 1;
  257. }
  258. return 0;
  259. }
  260. #define assert_nan(a) assert(isnan(a))
  261. #define check_nan(a) ({ assert_nan(a); a; })
  262. double __aeabi_i2d(int32_t);
  263. double __aeabi_ui2d(int32_t);
  264. double __aeabi_l2d(int64_t);
  265. double __aeabi_ul2d(int64_t);
  266. int32_t __aeabi_d2iz(double);
  267. int64_t __aeabi_d2lz(double);
  268. double __aeabi_dmul(double, double);
  269. double __aeabi_ddiv(double, double);
  270. #if LIB_PICO_DOUBLE_PICO
  271. double __real___aeabi_i2d(int);
  272. double __real___aeabi_ui2d(int);
  273. double __real___aeabi_l2d(int64_t);
  274. double __real___aeabi_ul2d(int64_t);
  275. double __real___aeabi_dmul(double, double);
  276. double __real___aeabi_ddiv(double, double);
  277. int32_t __real___aeabi_d2iz(double);
  278. int64_t __real___aeabi_d2lz(double);
  279. double __real_sqrt(double);
  280. double __real_cos(double);
  281. double __real_sin(double);
  282. double __real_tan(double);
  283. double __real_exp(double);
  284. double __real_log(double);
  285. double __real_atan2(double, double);
  286. double __real_pow(double, double);
  287. double __real_trunc(double);
  288. double __real_ldexp(double, int);
  289. double __real_fmod(double, double);
  290. #define EPSILON 1e-9
  291. #define assert_close(a, b) assert(((b - a) < EPSILON || (a - b) < EPSILON) || (isinf(a) && isinf(b) && (a < 0) == (b < 0)))
  292. #define check1(func,p0) ({ typeof(p0) r = func(p0), r2 = __CONCAT(__real_, func)(p0); assert(r == r2); r; })
  293. #define check2(func,p0,p1) ({ typeof(p0) r = func(p0,p1), r2 = __CONCAT(__real_, func)(p0,p1); assert(r == r2); r; })
  294. #define check_close1(func,p0) ({ typeof(p0) r = func(p0), r2 = __CONCAT(__real_, func)(p0); if (isnan(p0)) assert_nan(r); else assert_close(r, r2); r; })
  295. #define check_close2(func,p0,p1) ({ typeof(p0) r = func(p0,p1), r2 = __CONCAT(__real_, func)(p0,p1); if (isnan(p0) || isnan(p1)) assert_nan(r); else assert_close(r, r2); r; })
  296. #else
  297. #define check1(func,p0) func(p0)
  298. #define check2(func,p0,p1) func(p0,p1)
  299. #define check_close1(func,p0) func(p0)
  300. #define check_close2(func,p0,p1) func(p0,p1)
  301. #endif
  302. double aa = 0.5;
  303. double bb = 1;
  304. int main() {
  305. setup_default_uart();
  306. bool fail = false;
  307. printf("%d\n", aa < bb);
  308. for(double a = -1; a <= 1; a++) {
  309. for(double b = -1; b <= 1; b++) {
  310. printf("%f < %f ? %d\n", a, b, a < b);
  311. }
  312. }
  313. for(double a = -1; a <=1; a++) {
  314. for(double b = -1; b <= 1; b++) {
  315. printf("%f > %f ? %d\n", a, b, a > b);
  316. }
  317. }
  318. #if 1
  319. for (double x = 0; x < 3; x++) {
  320. printf("\n ----- %g\n", x);
  321. printf("SQRT %10.18g\n", check_close1(sqrt, x));
  322. printf("COS %10.18g\n", check_close1(cos, x));
  323. printf("SIN %10.18g\n", check_close1(sin, x));
  324. printf("TAN %10.18g\n", check_close1(tan, x));
  325. printf("ATAN2 %10.18g\n", check_close2(atan2, x, 10.0));
  326. printf("ATAN2 %10.18g\n", check_close2(atan2, 10.0, x));
  327. printf("EXP %10.18g\n", check_close1(exp, x));
  328. printf("LN %10.18g\n", check_close1(log, x));
  329. printf("POW %10.18f\n", check_close2(pow, x, x));
  330. printf("TRUNC %10.18f\n", check_close1(trunc, x));
  331. printf("LDEXP %10.18f\n", check_close2(ldexp, x, x));
  332. printf("FMOD %10.18f\n", check_close2(fmod, x, 3.0f));
  333. double s, c;
  334. sincos(x, &s, &c);
  335. printf("SINCOS %10.18f %10.18f\n", s, c);
  336. if (s != sin(x) || c != cos(x)) {
  337. printf("SINCOS mismatch\n");
  338. fail = true;
  339. }
  340. }
  341. #if PICO_DOUBLE_PROPAGATE_NANS
  342. {
  343. float x = NAN;
  344. printf("SQRT %10.18g\n", check_close1(sqrt, x));
  345. printf("COS %10.18g\n", check_close1(cos, x));
  346. printf("SIN %10.18g\n", check_close1(sin, x));
  347. printf("TAN %10.18g\n", check_close1(tan, x));
  348. printf("ATAN2 %10.18g\n", check_close2(atan2, x, 10.0));
  349. printf("ATAN2 %10.18g\n", check_close2(atan2, 10.0, x));
  350. printf("EXP %10.18g\n", check_close1(exp, x));
  351. printf("LN %10.18g\n", check_close1(log, x));
  352. printf("POW %10.18f\n", check_nan(pow(x, x)));
  353. printf("TRUNC %10.18f\n", check_nan(trunc(x)));
  354. printf("LDEXP %10.18f\n", check_nan(ldexp(x, x)));
  355. printf("FMOD %10.18f\n", check_nan(fmod(x, 3.0f)));
  356. double s, c;
  357. sincos(x, &s, &c);
  358. printf("SINCOS %10.18f %10.18f\n", check_nan(s), check_nan(c));
  359. for(int j=0;j<2;j++) {
  360. for (int i = 1; i < 4; i++) {
  361. char buf[4];
  362. sprintf(buf, "%d", i);
  363. float f0 = -nanf(buf);
  364. double d0 = -nan(buf);
  365. // hmm nanf/nan seem to ignore payload
  366. *(uint64_t *) &d0 |= i;
  367. *(uint32_t *) &f0 |= i;
  368. if (j) {
  369. // try without top bit set
  370. *(uint64_t *) &d0 &= ~0x0008000000000000ull;
  371. *(uint32_t *) &f0 &= ~0x00400000u;
  372. }
  373. float f = (float) d0;
  374. double d = (double) f0;
  375. printf("f2d %f %08"PRIx32" -> %g %016"PRIx64"\n", f0, *(uint32_t *) &f0, d, *(uint64_t *) &d);
  376. printf("d2f %f %016"PRIx64" -> %f %08"PRIx32"\n", d0, *(uint64_t *) &d0, f, *(uint32_t *) &f);
  377. }
  378. }
  379. }
  380. #endif
  381. {
  382. int32_t y;
  383. // for (int32_t x = 0; x>-512; x--) {
  384. // printf("i %d->%f\n", (int)x, (float) x);
  385. // }
  386. for (int32_t x = -1; x; x <<= 1) {
  387. printf("i %d->%f\n", x, (double) x);
  388. check1(__aeabi_i2d, x);
  389. }
  390. for (int32_t x = 1; x; x <<= 1) {
  391. printf("i %d->%f\n", x, (double) x);
  392. check1(__aeabi_i2d, x);
  393. y = x << 1;
  394. }
  395. for (int64_t x = 1; x; x <<= 1) {
  396. printf("i %lld->%f\n", x, (double) x);
  397. check1(__aeabi_l2d, x);
  398. y = x << 1;
  399. }
  400. for (int64_t x = -1; x; x <<= 1) {
  401. printf("i %lld->%f\n", x, (double) x);
  402. check1(__aeabi_l2d, x);
  403. y = x << 1;
  404. }
  405. printf("d %d->%f\n", y, (float) y);
  406. }
  407. {
  408. uint32_t y;
  409. for(uint32_t x = 1; x; x <<= 1) {
  410. printf("u %u->%f\n", x, (double)x);
  411. check1(__aeabi_ui2d, x);
  412. y = x << 1;
  413. }
  414. printf("u %u->%f\n", y, (double)y);
  415. }
  416. for(int64_t x = 1; x !=0; x <<= 1u) {
  417. printf("%lld->%f\n", x, (double)x);
  418. check1(__aeabi_l2d, x);
  419. }
  420. for(double x = -4294967296.f * 4294967296.f * 2.f; x<=-0.5f; x/=2.f) {
  421. printf("d2i64 %f->%lld\n", x, (int64_t)x);
  422. if (x < INT64_MIN) {
  423. // seems like there is a bug in the gcc version!
  424. assert(__aeabi_d2lz(x) == INT64_MIN);
  425. } else {
  426. check1(__aeabi_d2lz, x);
  427. }
  428. }
  429. for(double x = 4294967296.f * 4294967296.f * 2.f; x>=0.5f; x/=2.f) {
  430. printf("d2i64 %f->%lld\n", x, (int64_t)x);
  431. if (x >= INT64_MAX) {
  432. // seems like there is a bug in the gcc version!
  433. assert(__aeabi_d2lz(x) == INT64_MAX);
  434. } else {
  435. check1(__aeabi_d2lz, x);
  436. }
  437. }
  438. for(double x = -4294967296.f * 4294967296.f; x<=-0.5f; x/=2.f) {
  439. printf("d2i32 %f->%d\n", x, (int32_t)x);
  440. check1(__aeabi_d2iz, x);
  441. }
  442. for(double x = 4294967296.f * 4294967296.f; x>=0.5f; x/=2.f) {
  443. printf("d2i32 %f->%d\n", x, (int32_t)x);
  444. check1(__aeabi_d2iz, x);
  445. }
  446. for (double x = 1; x < 11; x += 2) {
  447. double f = x * x;
  448. double g = 1.0 / x;
  449. printf("%g %10.18g %10.18g, %10.18g, %10.18g %10.18g\n", x, f, x + 0.37777777777777777777777777777,
  450. x - 0.377777777777777777777777777777, g, 123456789.0 / x);
  451. check2(__aeabi_dmul, x, x);
  452. check2(__aeabi_ddiv, 1.0, x);
  453. }
  454. if (fail ||
  455. test_cdcmpeq() ||
  456. test_cdcmple() ||
  457. test_dcmpun() ||
  458. test_cmple_gt() ||
  459. test_cmplt_ge()) {
  460. printf("FAILED\n");
  461. return 1;
  462. } else {
  463. printf("PASSED\n");
  464. return 0;
  465. }
  466. #endif
  467. }