pico_float_test.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. //===-- aeabi_cfcmpeq.c - Test __aeabi_cfcmpeq ----------------------------===//
  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_cfcmpeq 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/float.h>
  18. #include "pico/stdlib.h"
  19. // Include sys/types.h before inttypes.h to work around issue with
  20. // certain versions of GCC and newlib which causes omission of PRIx64
  21. #include <sys/types.h>
  22. #include "inttypes.h"
  23. #define test_assert(x) ({ if (!(x)) { printf("Assertion failed: ");puts(#x);printf(" at " __FILE__ ":%d\n", __LINE__); exit(-1); } })
  24. extern int __aeabi_fcmpun(float a, float b);
  25. #if __arm__
  26. #include "call_apsr.h"
  27. extern __attribute__((pcs("aapcs"))) void __aeabi_cfcmpeq(float a, float b);
  28. int test__aeabi_cfcmpeq(float a, float b, int expected) {
  29. uint32_t cpsr_value = call_apsr_f(a, b, __aeabi_cfcmpeq);
  30. union cpsr cpsr = {.value = cpsr_value};
  31. if (expected != cpsr.flags.z) {
  32. printf("error in __aeabi_cfcmpeq(%f, %f) => Z = %08x, expected %08x\n",
  33. a, b, cpsr.flags.z, expected);
  34. return 1;
  35. }
  36. return 0;
  37. }
  38. #endif
  39. int test_cfcmpeq() {
  40. #if __arm__
  41. if (test__aeabi_cfcmpeq(1.0, 1.0, 1))
  42. return 1;
  43. if (test__aeabi_cfcmpeq(1234.567, 765.4321, 0))
  44. return 1;
  45. if (test__aeabi_cfcmpeq(-123.0, -678.0, 0))
  46. return 1;
  47. if (test__aeabi_cfcmpeq(0.0, -0.0, 1))
  48. return 1;
  49. if (test__aeabi_cfcmpeq(0.0, 0.0, 1))
  50. return 1;
  51. if (test__aeabi_cfcmpeq(-0.0, -0.0, 1))
  52. return 1;
  53. if (test__aeabi_cfcmpeq(-0.0, 0.0, 1))
  54. return 1;
  55. if (test__aeabi_cfcmpeq(0.0, -1.0, 0))
  56. return 1;
  57. if (test__aeabi_cfcmpeq(-0.0, -1.0, 0))
  58. return 1;
  59. if (test__aeabi_cfcmpeq(-1.0, 0.0, 0))
  60. return 1;
  61. if (test__aeabi_cfcmpeq(-1.0, -0.0, 0))
  62. return 1;
  63. if (test__aeabi_cfcmpeq(1.0, NAN, 0))
  64. return 1;
  65. if (test__aeabi_cfcmpeq(NAN, 1.0, 0))
  66. return 1;
  67. if (test__aeabi_cfcmpeq(NAN, NAN, 0))
  68. return 1;
  69. if (test__aeabi_cfcmpeq(INFINITY, 1.0, 0))
  70. return 1;
  71. if (test__aeabi_cfcmpeq(0.0, INFINITY, 0))
  72. return 1;
  73. if (test__aeabi_cfcmpeq(-INFINITY, 0.0, 0))
  74. return 1;
  75. if (test__aeabi_cfcmpeq(0.0, -INFINITY, 0))
  76. return 1;
  77. if (test__aeabi_cfcmpeq(INFINITY, INFINITY, 1))
  78. return 1;
  79. if (test__aeabi_cfcmpeq(-INFINITY, -INFINITY, 1))
  80. return 1;
  81. #else
  82. printf("skipped\n");
  83. #endif
  84. return 0;
  85. }
  86. #if __arm__
  87. extern __attribute__((pcs("aapcs"))) void __aeabi_cfcmple(float a, float b);
  88. extern __attribute__((pcs("aapcs"))) void __aeabi_cfrcmple(float a, float b);
  89. int test_fcmple_gt(float a, float b, int expected) {
  90. if ((a <= b) != expected) {
  91. printf("error in fcmple(%f, %f) => %d, expected %d\n",
  92. a, b, a <= b, expected);
  93. return 1;
  94. }
  95. if ((a > b) == expected && !isnanf(a) && !isnanf(b)) {
  96. printf("error in fcmpgt(%f, %f) => %d, expected %d\n",
  97. a, b, a > b, !expected);
  98. return 1;
  99. }
  100. return 0;
  101. }
  102. int test_fcmplt_ge(float a, float b, int expected) {
  103. if ((a < b) != expected) {
  104. printf("error in fcmplt(%f, %f) => %d, expected %d\n",
  105. a, b, a < b, expected);
  106. return 1;
  107. }
  108. if ((a >= b) == expected && !isnanf(a) && !isnanf(b)) {
  109. printf("error in fcmpge(%f, %f) => %d, expected %d\n",
  110. a, b, a >= b, !expected);
  111. return 1;
  112. }
  113. return 0;
  114. }
  115. int test__aeabi_cfcmple(float a, float b, int expected) {
  116. int32_t cpsr_value = call_apsr_f(a, b, __aeabi_cfcmple);
  117. int32_t r_cpsr_value = call_apsr_f(b, a, __aeabi_cfrcmple);
  118. int32_t cpsr_value2 = call_apsr_f(b, a, __aeabi_cfcmple);
  119. int32_t r_cpsr_value2 = call_apsr_f(a, b, __aeabi_cfrcmple);
  120. if (cpsr_value != r_cpsr_value) {
  121. printf("error: __aeabi_cfcmple(%f, %f) != __aeabi_cfrcmple(%f, %f)\n", a, b, b, a);
  122. return 1;
  123. }
  124. int expected_z, expected_c;
  125. if (expected == -1) {
  126. expected_z = 0;
  127. expected_c = 0;
  128. } else if (expected == 0) {
  129. expected_z = 1;
  130. expected_c = 1;
  131. } else {
  132. // a or b is NaN, or a > b
  133. expected_z = 0;
  134. expected_c = 1;
  135. }
  136. #if PICO_FLOAT_COMPILER
  137. // gcc has this backwards it seems - not a good thing, but I guess it doesn't ever call them
  138. expected_c ^= 1;
  139. #endif
  140. union cpsr cpsr = {.value = cpsr_value};
  141. if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
  142. printf("error in __aeabi_cfcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
  143. a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
  144. return 1;
  145. }
  146. cpsr.value = r_cpsr_value;
  147. if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
  148. printf("error in __aeabi_cfrcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
  149. a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
  150. return 1;
  151. }
  152. return 0;
  153. }
  154. #endif
  155. int test_cfcmple() {
  156. #if __arm__
  157. if (test__aeabi_cfcmple(1.0, 1.0, 0))
  158. return 1;
  159. if (test__aeabi_cfcmple(1234.567, 765.4321, 1))
  160. return 1;
  161. if (test__aeabi_cfcmple(765.4321, 1234.567, -1))
  162. return 1;
  163. if (test__aeabi_cfcmple(-123.0, -678.0, 1))
  164. return 1;
  165. if (test__aeabi_cfcmple(-678.0, -123.0, -1))
  166. return 1;
  167. if (test__aeabi_cfcmple(-123.0, 678.0, -1))
  168. return 1;
  169. if (test__aeabi_cfcmple(678.0, -123.0, 1))
  170. return 1;
  171. if (test__aeabi_cfcmple(0.0, -0.0, 0))
  172. return 1;
  173. if (test__aeabi_cfcmple(1.0, NAN, 1))
  174. return 1;
  175. if (test__aeabi_cfcmple(NAN, 1.0, 1))
  176. return 1;
  177. if (test__aeabi_cfcmple(NAN, NAN, 1))
  178. return 1;
  179. #else
  180. printf("skipped\n");
  181. #endif
  182. return 0;
  183. }
  184. int test_cmple_gt() {
  185. if (test_fcmple_gt(1.0, 1.0, 1))
  186. return 1;
  187. if (test_fcmple_gt(1234.567, 765.4321, 0))
  188. return 1;
  189. if (test_fcmple_gt(765.4321, 1234.567, 1))
  190. return 1;
  191. if (test_fcmple_gt(-123.0, -678.0, 0))
  192. return 1;
  193. if (test_fcmple_gt(-678.0, -123.0, 1))
  194. return 1;
  195. if (test_fcmple_gt(-123.0, 678.0, 1))
  196. return 1;
  197. if (test_fcmple_gt(678.0, -123.0, 0))
  198. return 1;
  199. if (test_fcmple_gt(0.0, -0.0, 1))
  200. return 1;
  201. if (test_fcmple_gt(-0.0, 0.0, 1))
  202. return 1;
  203. if (test_fcmple_gt(1.0, NAN, 0))
  204. return 1;
  205. if (test_fcmple_gt(NAN, 1.0, 0))
  206. return 1;
  207. if (test_fcmple_gt(NAN, NAN, 0))
  208. return 1;
  209. return 0;
  210. }
  211. int test_cmplt_ge() {
  212. if (test_fcmplt_ge(1.0, 1.0, 0))
  213. return 1;
  214. if (test_fcmplt_ge(1234.567, 765.4321, 0))
  215. return 1;
  216. if (test_fcmplt_ge(765.4321, 1234.567, 1))
  217. return 1;
  218. if (test_fcmplt_ge(-123.0, -678.0, 0))
  219. return 1;
  220. if (test_fcmplt_ge(-678.0, -123.0, 1))
  221. return 1;
  222. if (test_fcmplt_ge(-123.0, 678.0, 1))
  223. return 1;
  224. if (test_fcmplt_ge(678.0, -123.0, 0))
  225. return 1;
  226. if (test_fcmplt_ge(0.0, -0.0, 0))
  227. return 1;
  228. if (test_fcmplt_ge(-0.0, 0.0, 0))
  229. return 1;
  230. if (test_fcmplt_ge(1.0, NAN, 0))
  231. return 1;
  232. if (test_fcmplt_ge(NAN, 1.0, 0))
  233. return 1;
  234. if (test_fcmplt_ge(NAN, NAN, 0))
  235. return 1;
  236. return 0;
  237. }
  238. int check_fcmpun(float a, float b, bool expected, bool expect_equal) {
  239. if (__aeabi_fcmpun(a, b) != expected) {
  240. printf("Failed fcmpun(%f, %f)\n", a, b);
  241. return 1;
  242. }
  243. if ((a == b) != expect_equal) {
  244. printf("Failed equality check %f %f\n", a, b);
  245. __breakpoint();
  246. if (b == a) {
  247. printf("SAS\n");
  248. }
  249. return 1;
  250. }
  251. return 0;
  252. }
  253. int test_fcmpun() {
  254. if (check_fcmpun(0, 0, false, true) ||
  255. check_fcmpun(-INFINITY, INFINITY, false, false) ||
  256. check_fcmpun(NAN, 0, true, false) ||
  257. check_fcmpun(0, NAN, true, false) ||
  258. check_fcmpun(NAN, NAN, true, false) ||
  259. check_fcmpun(-NAN, NAN, true, false)) {
  260. return 1;
  261. }
  262. return 0;
  263. }
  264. #define assert_nan(a) test_assert(isnanf(a))
  265. #define check_nan(a) ({ assert_nan(a); a; })
  266. float __aeabi_i2f(int32_t);
  267. float __aeabi_ui2f(int32_t);
  268. float __aeabi_l2f(int64_t);
  269. float __aeabi_ul2f(int64_t);
  270. int32_t __aeabi_f2iz(float);
  271. int64_t __aeabi_f2lz(float);
  272. float __aeabi_fmul(float, float);
  273. float __aeabi_fdiv(float, float);
  274. #if LIB_PICO_FLOAT_PICO
  275. #if !LIB_PICO_FLOAT_PICO_VFP
  276. float __real___aeabi_i2f(int);
  277. float __real___aeabi_ui2f(int);
  278. float __real___aeabi_l2f(int64_t);
  279. float __real___aeabi_ul2f(int64_t);
  280. float __real___aeabi_fmul(float, float);
  281. float __real___aeabi_fdiv(float, float);
  282. int32_t __real___aeabi_f2iz(float);
  283. int64_t __real___aeabi_f2lz(float);
  284. float __real_sqrtf(float);
  285. #endif
  286. float __real_cosf(float);
  287. float __real_sinf(float);
  288. float __real_tanf(float);
  289. float __real_expf(float);
  290. float __real_logf(float);
  291. float __real_atan2f(float, float);
  292. float __real_powf(float, float);
  293. float __real_truncf(float);
  294. float __real_ldexpf(float, int);
  295. float __real_fmodf(float, float);
  296. #define FRAC ((float)(1u << 22))
  297. #define allowed_range(a) (fabsf(a) / FRAC)
  298. #ifdef LLVM_LIBC_MATH_H
  299. #define isinff isinf
  300. #endif
  301. #define assert_close(a, b) test_assert((fabsf(a - b) <= allowed_range(a) || ({ printf(" error: %f != %f\n", a, b); 0; })) || (isinff(a) && isinff(b) && (a < 0) == (b < 0)))
  302. #define check1(func,p0) ({ typeof(p0) r = func(p0), r2 = __CONCAT(__real_, func)(p0); test_assert(r == r2); r; })
  303. #define check2(func,p0,p1) ({ typeof(p0) r = func(p0,p1), r2 = __CONCAT(__real_, func)(p0,p1); test_assert(r == r2); r; })
  304. #define check_close1(func,p0) ({ typeof(p0) r = func(p0), r2 = __CONCAT(__real_, func)(p0); if (isnanf(p0)) assert_nan(r); else assert_close(r, r2); r; })
  305. #define check_close2(func,p0,p1) ({ typeof(p0) r = func(p0,p1), r2 = __CONCAT(__real_, func)(p0,p1); if (isnanf(p0) || isnanf(p1)) assert_nan(r); else assert_close(r, r2); r; })
  306. #else
  307. #define check1(func,p0) func(p0)
  308. #define check2(func,p0,p1) func(p0,p1)
  309. #define check_close1(func,p0) func(p0)
  310. #define check_close2(func,p0,p1) func(p0,p1)
  311. #endif
  312. double aa = 0.5;
  313. double bb = 1;
  314. int main() {
  315. setup_default_uart();
  316. bool fail = false;
  317. printf("%d\n", aa < bb);
  318. for(float a = -1; a <= 1; a++) {
  319. for(float b = -1; b <= 1; b++) {
  320. printf("%f < %f ? %d\n", a, b, a < b);
  321. }
  322. }
  323. for(float a = -1; a <=1; a++) {
  324. for(float b = -1; b <= 1; b++) {
  325. printf("%f > %f ? %d\n", a, b, a > b);
  326. }
  327. }
  328. printf("F\n");
  329. for(float f = -1.0; f<=1.f; f+=0.25f) {
  330. printf("%d\n", (int)f);
  331. }
  332. printf("D\n");
  333. for(double d = -1.0; d<=1.0; d+=0.25) {
  334. printf("%d\n", (int)d);
  335. }
  336. printf("LD\n");
  337. for(double d = -1.0; d<=1.0; d+=0.25) {
  338. printf("%lld\n", (int64_t)d);
  339. }
  340. for(float d = -0.125; d>=-65536.0*65536.0*65536.0*65536.0*2; d*=2) {
  341. printf("%g %d, %lld, %u, %llu\n", d, (int32_t)d, (int64_t)d, (uint32_t)d, (uint64_t)d);
  342. }
  343. for(float d = 0.125; d<=65536.0*65536.0*65536.0*65536.0*2; d*=2) {
  344. printf("%g %d, %lld, %u, %llu\n", d, (int32_t)d, (int64_t)d, (uint32_t)d, (uint64_t)d);
  345. }
  346. for(double d = -0.125; d>=-65536.0*65536.0*65536.0*65536.0*2; d*=2) {
  347. printf("%g %d, %lld, %u, %llu\n", d, (int32_t)d, (int64_t)d, (uint32_t)d, (uint64_t)d);
  348. }
  349. for(double d = 0.125; d<=65536.0*65536.0*65536.0*65536.0*2; d*=2) {
  350. printf("%g %d, %lld, %u, %llu\n", d, (int32_t)d, (int64_t)d, (uint32_t)d, (uint64_t)d);
  351. }
  352. for(int i = (int32_t)0x80000000; i <0; i /= 2) {
  353. printf("%d %f\n", i, (double)i);
  354. }
  355. for(int i = (1<<30); i >0; i /= 2) {
  356. printf("%d %f\n", i, (double)i);
  357. }
  358. printf("%f\n", 0.5);
  359. printf("SQRT %10.18g\n", 0.5);
  360. printf("SQRT %10.18g\n", 0.333333333333333333333333);
  361. #if 1
  362. for (float x = 0; x < 3; x++) {
  363. printf("\n ----- %f\n", x);
  364. #if !LIB_PICO_FLOAT_PICO_VFP
  365. printf("FSQRT %10.18f\n", check_close1(sqrtf, x));
  366. #endif
  367. printf("FCOS %10.18f\n", check_close1(cosf, x));
  368. printf("FSIN %10.18f\n", check_close1(sinf, x));
  369. float s, c;
  370. sincosf(x, &s, &c);
  371. printf("FSINCOS %10.18f %10.18f\n", s, c);
  372. printf("FTAN %10.18f\n", check_close1(tanf, x));
  373. printf("FATAN2 %10.18f\n", check_close2(atan2f, x, 10.f));
  374. printf("FATAN2 %10.18f\n", check_close2(atan2f, 10.f, x));
  375. printf("FEXP %10.18f\n", check_close1(expf, x));
  376. printf("FLN %10.18f\n", check_close1(logf, x));
  377. printf("POWF %10.18f\n", check_close2(powf, x, x));
  378. // todo clang why does this not compile?
  379. #ifndef __clang__
  380. printf("TRUNCF %10.18f\n", check_close1(truncf, x));
  381. #endif
  382. printf("LDEXPF %10.18f\n", check_close2(ldexpf, x, x));
  383. printf("FMODF %10.18f\n", check_close2(fmodf, x, 3.0f));
  384. sincosf(x, &s, &c);
  385. printf("SINCOS %10.18f %10.18f\n", s, c);
  386. if (s != sinf(x) || c != cosf(x)) {
  387. printf("SINCOS mismatch\n");
  388. fail = true;
  389. }
  390. }
  391. for (double x = 0; x < 3; x++) {
  392. printf("\n ----- %g\n", x);
  393. printf("SQRT %10.18g\n", sqrt(x));
  394. printf("COS %10.18g\n", cos(x));
  395. printf("SIN %10.18g\n", sin(x));
  396. printf("TAN %10.18g\n", tan(x));
  397. printf("ATAN2 %10.18g\n", atan2(x, 10));
  398. printf("ATAN2 %10.18g\n", atan2(10, x));
  399. printf("EXP %10.18g\n", exp(x));
  400. printf("LN %10.18g\n", log(x));
  401. }
  402. #if PICO_FLOAT_PROPAGATE_NANS
  403. {
  404. float x = NAN;
  405. printf("NANO %10.18f\n", x);
  406. printf("FSQRT %10.18f\n", sqrtf(x));
  407. printf("FCOS %10.18f\n", cosf(x));
  408. printf("FSIN %10.18f\n", sinf(x));
  409. printf("FTAN %10.18f\n", tanf(x));
  410. printf("FATAN2 %10.18f\n", atan2f(x, 10));
  411. printf("FATAN2 %10.18f\n", atan2f(10, x));
  412. printf("FEXP %10.18f\n", expf(x));
  413. printf("FLN %10.18f\n", logf(x));
  414. printf("POWF %10.18f\n", powf(x, x));
  415. printf("TRUNCF %10.18f\n", truncf(x));
  416. printf("LDEXPF %10.18f\n", ldexpf(x, x));
  417. printf("FMODF %10.18f\n", fmodf(x, 3.0f));
  418. float s, c;
  419. // sincosf(x, &s, &c);
  420. printf("FSINCOS %10.18f %10.18f\n", s, c);
  421. for(int j=0;j<2;j++) {
  422. for (int i = 1; i < 4; i++) {
  423. char buf[4];
  424. sprintf(buf, "%d", i);
  425. float f0 = -nanf(buf);
  426. double d0 = -nan(buf);
  427. // hmm nanf/nan seem to ignore payload
  428. *(uint64_t *) &d0 |= i;
  429. *(uint32_t *) &f0 |= i;
  430. if (j) {
  431. // try without top bit set
  432. *(uint64_t *) &d0 &= ~0x0008000000000000ull;
  433. *(uint32_t *) &f0 &= ~0x00400000u;
  434. }
  435. float f = (float) d0;
  436. double d = (double) f0;
  437. printf("f2d %f %08"PRIx32" -> %g %016"PRIx64"\n", f0, *(uint32_t *) &f0, d, *(uint64_t *) &d);
  438. printf("d2f %f %016"PRIx64" -> %f %08"PRIx32"\n", d0, *(uint64_t *) &d0, f, *(uint32_t *) &f);
  439. }
  440. }
  441. }
  442. #endif
  443. #if !LIB_PICO_FLOAT_PICO_VFP
  444. {
  445. int32_t y;
  446. // for (int32_t x = 0; x>-512; x--) {
  447. // printf("i %d->%f\n", (int)x, (float) x);
  448. // }
  449. for (int32_t x = -1; x; x <<= 1) {
  450. printf("i %d->%f\n", x, (float) x);
  451. check1(__aeabi_i2f, x);
  452. }
  453. for (int32_t x = 1; x; x <<= 1) {
  454. printf("i %d->%f\n", x, (float) x);
  455. check1(__aeabi_i2f, x);
  456. y = x << 1;
  457. }
  458. for (int64_t x = 1; x; x <<= 1) {
  459. printf("i %lld->%f\n", x, (float) x);
  460. check1(__aeabi_l2f, x);
  461. y = x << 1;
  462. }
  463. for (int64_t x = -1; x; x <<= 1) {
  464. printf("i %lld->%f\n", x, (float) x);
  465. check1(__aeabi_l2f, x);
  466. y = x << 1;
  467. }
  468. printf("d %d->%f\n", y, (float) y);
  469. }
  470. {
  471. uint32_t y;
  472. for(uint32_t x = 1; x; x <<= 1) {
  473. printf("u %u->%f\n", x, (float)x);
  474. check1(__aeabi_ui2f, x);
  475. y = x << 1;
  476. }
  477. printf("u %u->%f\n", y, (float)y);
  478. }
  479. for(int64_t x = 1; x !=0; x <<= 1u) {
  480. printf("%lld->%f\n", x, (float)x);
  481. check1(__aeabi_l2f, x);
  482. }
  483. for(float x = -4294967296.f * 4294967296.f; x>=0.5f; x/=2.f) {
  484. printf("f %f->%lld\n", x, (int64_t)x);
  485. check1(__aeabi_f2lz, x);
  486. }
  487. for(float x = 4294967296.f * 4294967296.f * 2.f; x>=0.5f; x/=2.f) {
  488. printf("f2i64 %f->%lld\n", x, (int64_t)x);
  489. #if PICO_RP2040
  490. if ((double)x >= (double)INT64_MAX) {
  491. // seems like there is a bug in the gcc version (which returns UINT64_MAX)
  492. test_assert(__aeabi_f2lz(x) == INT64_MAX);
  493. } else {
  494. check1(__aeabi_f2lz, x);
  495. }
  496. #else
  497. check1(__aeabi_f2lz, x);
  498. #endif
  499. }
  500. for(float x = -4294967296.f * 4294967296.f; x<=-0.5f; x/=2.f) {
  501. printf("d2i32 %f->%d\n", x, (int32_t)x);
  502. check1(__aeabi_f2iz, x);
  503. }
  504. for(float x = 4294967296.f * 4294967296.f; x>=0.5f; x/=2.f) {
  505. printf("d2i32 %f->%d\n", x, (int32_t)x);
  506. #if PICO_RP2040
  507. if ((double)x >= (double)INT32_MAX) {
  508. // seems like there is a bug in the clang version (which returns INT32_MIN)
  509. test_assert(__aeabi_f2iz(x) == INT32_MAX);
  510. } else {
  511. check1(__aeabi_f2iz, x);
  512. }
  513. #else
  514. check1(__aeabi_f2iz, x);
  515. #endif
  516. }
  517. for (float x = 1; x < 11; x += 2) {
  518. float f = x * x;
  519. float g = 1.0f / x;
  520. printf("%g %10.18g %10.18g, %10.18g, %10.18g %10.18g\n", x, f, x + 0.37777777777777777777777777777f,
  521. x - 0.377777777777777777777777777777f, g, 123456789.0f / x);
  522. check2(__aeabi_fmul, x, x);
  523. check2(__aeabi_fdiv, 1.0f, x);
  524. }
  525. #endif
  526. if (fail ||
  527. test_cfcmpeq() ||
  528. test_cfcmple() ||
  529. test_fcmpun() ||
  530. test_cmple_gt() ||
  531. test_cmplt_ge()) {
  532. printf("FAILED\n");
  533. return 1;
  534. } else {
  535. printf("PASSED\n");
  536. return 0;
  537. }
  538. #endif
  539. }
  540. #if 0
  541. // todo need to add tests like these
  542. bool __noinline check(float x, float y) {
  543. return x > y;
  544. }
  545. bool __noinline checkd(double x, double y) {
  546. return x >= y;
  547. }
  548. int main() {
  549. stdio_init_all();
  550. #if 0
  551. printf("0 op nan %d\n", check(0, nanf("sd")));
  552. printf("nan op 0 %d\n", check(nanf("sd"), 0));
  553. printf("0 op -nan %d\n", check(0, -nanf("sd")));
  554. printf("-nan op 0 %d\n", check(-nanf("sd"), 0));
  555. printf("-nan op nan %d\n", check(-nanf("xx"), nanf("xx")));
  556. printf("-nan op -nan %d\n", check(-nanf("xx"), -nanf("xx")));
  557. printf("nan op -nan %d\n", check(nanf("xx"), -nanf("xx")));
  558. printf("nan op nan %d\n", check(nanf("xx"), nanf("xx")));
  559. printf("0 op inf %d\n", check(0, infinityf()));
  560. printf("inf op 0 %d\n", check(infinityf(), 0));
  561. printf("0 op -inf %d\n", check(0, -infinityf()));
  562. printf("-inf op 0 %d\n", check(-infinityf(), 0));
  563. printf("-inf op inf %d\n", check(-infinityf(), infinityf()));
  564. printf("-inf op -inf %d\n", check(-infinityf(), -infinityf()));
  565. printf("inf op -inf %d\n", check(infinityf(), -infinityf()));
  566. printf("inf op inf %d\n", check(infinityf(), infinityf()));
  567. printf("1 op 1 %d\n", check(1, 1));
  568. printf("-1 op 1 %d\n", check(-1, 1));
  569. printf("1 op -1 %d\n", check(1, -1));
  570. printf("-1 op -1 %d\n", check(-1, -1));
  571. printf("1 op 2 %d\n", check(1, 2));
  572. printf("2 op 1 %d\n", check(2, 1));
  573. printf("-1 op -2 %d\n", check(-1, -2));
  574. printf("-2 op -1 %d\n", check(-2, -1));
  575. #else
  576. printf("0 op nan %d\n", checkd(0, nan("sd")));
  577. printf("nan op 0 %d\n", checkd(nan("sd"), 0));
  578. printf("0 op -nan %d\n", checkd(0, -nan("sd")));
  579. printf("-nan op 0 %d\n", checkd(-nan("sd"), 0));
  580. printf("-nan op nan %d\n", checkd(-nan("xx"), nan("xx")));
  581. printf("-nan op -nan %d\n", checkd(-nan("xx"), -nan("xx")));
  582. printf("nan op -nan %d\n", checkd(nan("xx"), -nan("xx")));
  583. printf("nan op nan %d\n", checkd(nan("xx"), nan("xx")));
  584. printf("0 op inf %d\n", checkd(0, infinity()));
  585. printf("inf op 0 %d\n", checkd(infinity(), 0));
  586. printf("0 op -inf %d\n", checkd(0, -infinity()));
  587. printf("-inf op 0 %d\n", checkd(-infinity(), 0));
  588. printf("-inf op inf %d\n", checkd(-infinity(), infinity()));
  589. printf("-inf op -inf %d\n", checkd(-infinity(), -infinity()));
  590. printf("inf op -inf %d\n", checkd(infinity(), -infinity()));
  591. printf("inf op inf %d\n", checkd(infinity(), infinity()));
  592. printf("1 op 1 %d\n", checkd(1, 1));
  593. printf("-1 op 1 %d\n", checkd(-1, 1));
  594. printf("1 op -1 %d\n", checkd(1, -1));
  595. printf("-1 op -1 %d\n", checkd(-1, -1));
  596. printf("1 op 2 %d\n", checkd(1, 2));
  597. printf("2 op 1 %d\n", checkd(2, 1));
  598. printf("-1 op -2 %d\n", checkd(-1, -2));
  599. printf("-2 op -1 %d\n", checkd(-2, -1));
  600. #endif
  601. }
  602. #endif