fpu-tst.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. #define ASSERT(EXPRESSION) \
  2. do { \
  3. if (!(EXPRESSION)) { \
  4. fprintf (stderr, "%s:%d: assertion failed - %s\n", \
  5. __FILE__, __LINE__, #EXPRESSION); \
  6. abort (); \
  7. } \
  8. } while (0)
  9. #define SIM_BITS_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE)
  10. #include "milieu.h"
  11. #include "softfloat.h"
  12. #include "systfloat.h"
  13. #include "systmodes.h"
  14. /* #define SIM_FPU_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE) */
  15. #include "sim-bits.h"
  16. #include "sim-fpu.h"
  17. #include "sim-fpu.c"
  18. static int flags;
  19. int8_t
  20. syst_float_flags_clear ()
  21. {
  22. int old_flags = 0;
  23. int i = 1;
  24. while (flags >= i)
  25. {
  26. switch ((sim_fpu_status) (flags & i))
  27. {
  28. case sim_fpu_status_denorm:
  29. break;
  30. case sim_fpu_status_invalid_snan:
  31. case sim_fpu_status_invalid_qnan:
  32. case sim_fpu_status_invalid_isi:
  33. case sim_fpu_status_invalid_idi:
  34. case sim_fpu_status_invalid_zdz:
  35. case sim_fpu_status_invalid_imz:
  36. case sim_fpu_status_invalid_cvi:
  37. case sim_fpu_status_invalid_cmp:
  38. case sim_fpu_status_invalid_sqrt:
  39. old_flags |= float_flag_invalid; /* v */
  40. break;
  41. case sim_fpu_status_inexact:
  42. old_flags |= float_flag_inexact; /* x */
  43. break;
  44. case sim_fpu_status_overflow:
  45. old_flags |= float_flag_overflow; /* o */
  46. break;
  47. case sim_fpu_status_underflow:
  48. old_flags |= float_flag_underflow; /* u */
  49. break;
  50. case sim_fpu_status_invalid_div0:
  51. old_flags |= float_flag_divbyzero; /* z */
  52. break;
  53. case sim_fpu_status_rounded:
  54. break;
  55. }
  56. i <<= 1;
  57. }
  58. flags = 0;
  59. return old_flags;
  60. }
  61. sim_fpu_round rounding_mode;
  62. void
  63. syst_float_set_rounding_mode(int8_t mode)
  64. {
  65. switch (mode)
  66. {
  67. case float_round_nearest_even:
  68. rounding_mode = sim_fpu_round_near;
  69. break;
  70. case float_round_down:
  71. rounding_mode = sim_fpu_round_down;
  72. break;
  73. case float_round_up:
  74. rounding_mode = sim_fpu_round_up;
  75. break;
  76. case float_round_to_zero:
  77. rounding_mode = sim_fpu_round_zero;
  78. break;
  79. }
  80. }
  81. float32
  82. syst_int32_to_float32(int32_t a)
  83. {
  84. float32 z;
  85. sim_fpu s;
  86. flags |= sim_fpu_i32to (&s, a, rounding_mode);
  87. flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
  88. sim_fpu_to32 (&z, &s);
  89. return z;
  90. }
  91. float64
  92. syst_int32_to_float64( int32_t a )
  93. {
  94. float64 z;
  95. sim_fpu s;
  96. flags |= sim_fpu_i32to (&s, a, rounding_mode);
  97. sim_fpu_to64 (&z, &s);
  98. return z;
  99. }
  100. int32_t
  101. syst_float32_to_int32_round_to_zero( float32 a )
  102. {
  103. int32_t z;
  104. sim_fpu s;
  105. sim_fpu_32to (&s, a);
  106. flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
  107. return z;
  108. }
  109. float64
  110. syst_float32_to_float64 (float32 a)
  111. {
  112. float64 z;
  113. sim_fpu s;
  114. sim_fpu_32to (&s, a);
  115. flags |= sim_fpu_round_64 (&s, rounding_mode, 0);
  116. sim_fpu_to64 (&z, &s);
  117. return z;
  118. }
  119. float32 syst_float32_add( float32 a, float32 b )
  120. {
  121. float32 z;
  122. sim_fpu A;
  123. sim_fpu B;
  124. sim_fpu ans;
  125. sim_fpu_32to (&A, a);
  126. sim_fpu_32to (&B, b);
  127. #if 0
  128. fprintf (stdout, "\n ");
  129. sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
  130. fprintf (stdout, "\n+ ");
  131. sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
  132. fprintf (stdout, "\n= ");
  133. #endif
  134. flags |= sim_fpu_add (&ans, &A, &B);
  135. flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
  136. #if 0
  137. sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
  138. fprintf (stdout, "\n");
  139. #endif
  140. sim_fpu_to32 (&z, &ans);
  141. return z;
  142. }
  143. float32 syst_float32_sub( float32 a, float32 b )
  144. {
  145. float32 z;
  146. sim_fpu A;
  147. sim_fpu B;
  148. sim_fpu ans;
  149. sim_fpu_32to (&A, a);
  150. sim_fpu_32to (&B, b);
  151. #if 0
  152. sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
  153. fprintf (stdout, " + ");
  154. sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
  155. fprintf (stdout, " = ");
  156. #endif
  157. flags |= sim_fpu_sub (&ans, &A, &B);
  158. flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
  159. #if 0
  160. sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
  161. fprintf (stdout, "\n");
  162. #endif
  163. sim_fpu_to32 (&z, &ans);
  164. return z;
  165. }
  166. float32 syst_float32_mul( float32 a, float32 b )
  167. {
  168. float32 z;
  169. sim_fpu A;
  170. sim_fpu B;
  171. sim_fpu ans;
  172. sim_fpu_32to (&A, a);
  173. sim_fpu_32to (&B, b);
  174. #if 0
  175. sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
  176. fprintf (stdout, " + ");
  177. sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
  178. fprintf (stdout, " = ");
  179. #endif
  180. flags |= sim_fpu_mul (&ans, &A, &B);
  181. #if 0
  182. sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
  183. #endif
  184. flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
  185. #if 0
  186. sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
  187. fprintf (stdout, "\n");
  188. #endif
  189. sim_fpu_to32 (&z, &ans);
  190. return z;
  191. }
  192. float32 syst_float32_div( float32 a, float32 b )
  193. {
  194. float32 z;
  195. sim_fpu A;
  196. sim_fpu B;
  197. sim_fpu ans;
  198. sim_fpu_32to (&A, a);
  199. sim_fpu_32to (&B, b);
  200. flags |= sim_fpu_div (&ans, &A, &B);
  201. flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
  202. sim_fpu_to32 (&z, &ans);
  203. return z;
  204. }
  205. float32 syst_float32_sqrt( float32 a )
  206. {
  207. float32 z;
  208. sim_fpu A;
  209. sim_fpu ans;
  210. sim_fpu_32to (&A, a);
  211. #if 0
  212. sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
  213. fprintf (stdout, " sqrt> ");
  214. #endif
  215. flags |= sim_fpu_sqrt (&ans, &A);
  216. #if 0
  217. sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
  218. #endif
  219. flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
  220. #if 0
  221. fprintf (stdout, " (%x)\n", flags);
  222. #endif
  223. sim_fpu_to32 (&z, &ans);
  224. return z;
  225. }
  226. flag syst_float32_eq( float32 a, float32 b )
  227. {
  228. sim_fpu A;
  229. sim_fpu B;
  230. int is;
  231. sim_fpu_32to (&A, a);
  232. sim_fpu_32to (&B, b);
  233. flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
  234. return is;
  235. }
  236. flag syst_float32_eq_signaling( float32 a, float32 b )
  237. {
  238. sim_fpu A;
  239. sim_fpu B;
  240. int is;
  241. sim_fpu_32to (&A, a);
  242. sim_fpu_32to (&B, b);
  243. flags |= sim_fpu_eq (&is, &A, &B);
  244. return is;
  245. }
  246. flag syst_float32_le( float32 a, float32 b )
  247. {
  248. sim_fpu A;
  249. sim_fpu B;
  250. int is;
  251. sim_fpu_32to (&A, a);
  252. sim_fpu_32to (&B, b);
  253. flags |= sim_fpu_le (&is, &A, &B);
  254. return is;
  255. }
  256. flag syst_float32_le_quiet( float32 a, float32 b )
  257. {
  258. sim_fpu A;
  259. sim_fpu B;
  260. int is;
  261. sim_fpu_32to (&A, a);
  262. sim_fpu_32to (&B, b);
  263. flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
  264. return is;
  265. }
  266. flag syst_float32_lt( float32 a, float32 b )
  267. {
  268. sim_fpu A;
  269. sim_fpu B;
  270. int is;
  271. sim_fpu_32to (&A, a);
  272. sim_fpu_32to (&B, b);
  273. flags |= sim_fpu_lt (&is, &A, &B);
  274. return is;
  275. }
  276. flag syst_float32_lt_quiet( float32 a, float32 b )
  277. {
  278. sim_fpu A;
  279. sim_fpu B;
  280. int is;
  281. sim_fpu_32to (&A, a);
  282. sim_fpu_32to (&B, b);
  283. flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
  284. return is;
  285. }
  286. int32_t syst_float64_to_int32_round_to_zero( float64 a )
  287. {
  288. int32_t z;
  289. sim_fpu s;
  290. sim_fpu_64to (&s, a);
  291. flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
  292. return z;
  293. }
  294. float32 syst_float64_to_float32( float64 a )
  295. {
  296. float32 z;
  297. sim_fpu s;
  298. sim_fpu_64to (&s, a);
  299. #if 0
  300. sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
  301. fprintf (stdout, " -> ");
  302. #endif
  303. flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
  304. #if 0
  305. sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
  306. sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
  307. printf ("\n");
  308. #endif
  309. sim_fpu_to32 (&z, &s);
  310. return z;
  311. }
  312. float64 syst_float64_add( float64 a, float64 b )
  313. {
  314. float64 z;
  315. sim_fpu A;
  316. sim_fpu B;
  317. sim_fpu ans;
  318. sim_fpu_64to (&A, a);
  319. sim_fpu_64to (&B, b);
  320. #if 0
  321. sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
  322. fprintf (stdout, " + ");
  323. sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
  324. fprintf (stdout, " = ");
  325. #endif
  326. flags |= sim_fpu_add (&ans, &A, &B);
  327. #if 0
  328. sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
  329. #endif
  330. flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
  331. #if 0
  332. fprintf (stdout, " (%x)\n", flags);
  333. #endif
  334. sim_fpu_to64 (&z, &ans);
  335. return z;
  336. }
  337. float64 syst_float64_sub( float64 a, float64 b )
  338. {
  339. float64 z;
  340. sim_fpu A;
  341. sim_fpu B;
  342. sim_fpu ans;
  343. sim_fpu_64to (&A, a);
  344. sim_fpu_64to (&B, b);
  345. #if 0
  346. sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
  347. fprintf (stdout, " + ");
  348. sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
  349. fprintf (stdout, " = ");
  350. #endif
  351. flags |= sim_fpu_sub (&ans, &A, &B);
  352. #if 0
  353. sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
  354. #endif
  355. flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
  356. #if 0
  357. fprintf (stdout, " (%x)\n", flags);
  358. #endif
  359. sim_fpu_to64 (&z, &ans);
  360. return z;
  361. }
  362. float64 syst_float64_mul( float64 a, float64 b )
  363. {
  364. float64 z;
  365. sim_fpu A;
  366. sim_fpu B;
  367. sim_fpu ans;
  368. sim_fpu_64to (&A, a);
  369. sim_fpu_64to (&B, b);
  370. #if 0
  371. sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
  372. fprintf (stdout, " * ");
  373. sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
  374. fprintf (stdout, " = ");
  375. #endif
  376. flags |= sim_fpu_mul (&ans, &A, &B);
  377. #if 0
  378. sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
  379. #endif
  380. flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
  381. #if 0
  382. sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
  383. fprintf (stdout, "\n");
  384. #endif
  385. sim_fpu_to64 (&z, &ans);
  386. return z;
  387. }
  388. float64 syst_float64_div( float64 a, float64 b )
  389. {
  390. float64 z;
  391. sim_fpu A;
  392. sim_fpu B;
  393. sim_fpu ans;
  394. sim_fpu_64to (&A, a);
  395. sim_fpu_64to (&B, b);
  396. #if 0
  397. sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
  398. fprintf (stdout, " + ");
  399. sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
  400. fprintf (stdout, " = ");
  401. #endif
  402. flags |= sim_fpu_div (&ans, &A, &B);
  403. #if 0
  404. sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
  405. #endif
  406. flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
  407. #if 0
  408. sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
  409. fprintf (stdout, "\n");
  410. #endif
  411. sim_fpu_to64 (&z, &ans);
  412. return z;
  413. }
  414. float64 syst_float64_sqrt( float64 a )
  415. {
  416. float64 z;
  417. sim_fpu A;
  418. sim_fpu ans;
  419. sim_fpu_64to (&A, a);
  420. #if 0
  421. sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
  422. printf (" sqrt> ");
  423. printf ("\n");
  424. #endif
  425. flags |= sim_fpu_sqrt (&ans, &A);
  426. #if 0
  427. sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
  428. #endif
  429. flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
  430. #if 0
  431. sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
  432. fprintf (stdout, "\n");
  433. #endif
  434. sim_fpu_to64 (&z, &ans);
  435. return z;
  436. }
  437. flag syst_float64_eq( float64 a, float64 b )
  438. {
  439. sim_fpu A;
  440. sim_fpu B;
  441. int is;
  442. sim_fpu_64to (&A, a);
  443. sim_fpu_64to (&B, b);
  444. flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
  445. return is;
  446. }
  447. flag syst_float64_eq_signaling( float64 a, float64 b )
  448. {
  449. sim_fpu A;
  450. sim_fpu B;
  451. int is;
  452. sim_fpu_64to (&A, a);
  453. sim_fpu_64to (&B, b);
  454. flags |= sim_fpu_eq (&is, &A, &B);
  455. return is;
  456. }
  457. flag syst_float64_le( float64 a, float64 b )
  458. {
  459. sim_fpu A;
  460. sim_fpu B;
  461. int is;
  462. sim_fpu_64to (&A, a);
  463. sim_fpu_64to (&B, b);
  464. flags |= sim_fpu_le (&is, &A, &B);
  465. return is;
  466. }
  467. flag syst_float64_le_quiet( float64 a, float64 b )
  468. {
  469. sim_fpu A;
  470. sim_fpu B;
  471. int is;
  472. sim_fpu_64to (&A, a);
  473. sim_fpu_64to (&B, b);
  474. flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
  475. return is;
  476. }
  477. flag syst_float64_lt( float64 a, float64 b )
  478. {
  479. sim_fpu A;
  480. sim_fpu B;
  481. int is;
  482. sim_fpu_64to (&A, a);
  483. sim_fpu_64to (&B, b);
  484. flags |= sim_fpu_lt (&is, &A, &B);
  485. return is;
  486. }
  487. flag syst_float64_lt_quiet( float64 a, float64 b )
  488. {
  489. sim_fpu A;
  490. sim_fpu B;
  491. int is;
  492. sim_fpu_64to (&A, a);
  493. sim_fpu_64to (&B, b);
  494. flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
  495. return is;
  496. }