build.rs 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420
  1. use rand::seq::SliceRandom;
  2. use rand::Rng;
  3. use std::collections::HashMap;
  4. use std::fmt;
  5. use std::fmt::Write as FmtWrite;
  6. use std::fs::{self, OpenOptions};
  7. use std::hash::{Hash, Hasher};
  8. use std::io::Write;
  9. use std::path::PathBuf;
  10. use std::{env, mem};
  11. const NTESTS: usize = 1_000;
  12. fn main() {
  13. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  14. let out_file = out_dir.join("generated.rs");
  15. drop(fs::remove_file(&out_file));
  16. let target = env::var("TARGET").unwrap();
  17. let target_arch_arm = target.contains("arm") || target.contains("thumb");
  18. let target_arch_mips = target.contains("mips");
  19. // TODO accept NaNs. We don't do that right now because we can't check
  20. // for NaN-ness on the thumb targets (due to missing intrinsics)
  21. // float/add.rs
  22. gen(
  23. |(a, b): (MyF64, MyF64)| {
  24. let c = a.0 + b.0;
  25. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  26. None
  27. } else {
  28. Some(c)
  29. }
  30. },
  31. "builtins::float::add::__adddf3(a, b)",
  32. );
  33. gen(
  34. |(a, b): (MyF32, MyF32)| {
  35. let c = a.0 + b.0;
  36. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  37. None
  38. } else {
  39. Some(c)
  40. }
  41. },
  42. "builtins::float::add::__addsf3(a, b)",
  43. );
  44. if target_arch_arm {
  45. gen(
  46. |(a, b): (MyF64, MyF64)| {
  47. let c = a.0 + b.0;
  48. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  49. None
  50. } else {
  51. Some(c)
  52. }
  53. },
  54. "builtins::float::add::__adddf3vfp(a, b)",
  55. );
  56. gen(
  57. |(a, b): (LargeF32, LargeF32)| {
  58. let c = a.0 + b.0;
  59. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  60. None
  61. } else {
  62. Some(c)
  63. }
  64. },
  65. "builtins::float::add::__addsf3vfp(a, b)",
  66. );
  67. }
  68. // float/cmp.rs
  69. gen(
  70. |(a, b): (MyF64, MyF64)| {
  71. let (a, b) = (a.0, b.0);
  72. if a.is_nan() || b.is_nan() {
  73. return None;
  74. }
  75. if a.is_nan() || b.is_nan() {
  76. Some(-1)
  77. } else if a < b {
  78. Some(-1)
  79. } else if a > b {
  80. Some(1)
  81. } else {
  82. Some(0)
  83. }
  84. },
  85. "builtins::float::cmp::__gedf2(a, b)",
  86. );
  87. gen(
  88. |(a, b): (MyF32, MyF32)| {
  89. let (a, b) = (a.0, b.0);
  90. if a.is_nan() || b.is_nan() {
  91. return None;
  92. }
  93. if a.is_nan() || b.is_nan() {
  94. Some(-1)
  95. } else if a < b {
  96. Some(-1)
  97. } else if a > b {
  98. Some(1)
  99. } else {
  100. Some(0)
  101. }
  102. },
  103. "builtins::float::cmp::__gesf2(a, b)",
  104. );
  105. gen(
  106. |(a, b): (MyF64, MyF64)| {
  107. let (a, b) = (a.0, b.0);
  108. if a.is_nan() || b.is_nan() {
  109. return None;
  110. }
  111. if a.is_nan() || b.is_nan() {
  112. Some(1)
  113. } else if a < b {
  114. Some(-1)
  115. } else if a > b {
  116. Some(1)
  117. } else {
  118. Some(0)
  119. }
  120. },
  121. "builtins::float::cmp::__ledf2(a, b)",
  122. );
  123. gen(
  124. |(a, b): (MyF32, MyF32)| {
  125. let (a, b) = (a.0, b.0);
  126. if a.is_nan() || b.is_nan() {
  127. return None;
  128. }
  129. if a.is_nan() || b.is_nan() {
  130. Some(1)
  131. } else if a < b {
  132. Some(-1)
  133. } else if a > b {
  134. Some(1)
  135. } else {
  136. Some(0)
  137. }
  138. },
  139. "builtins::float::cmp::__lesf2(a, b)",
  140. );
  141. gen(
  142. |(a, b): (MyF32, MyF32)| {
  143. let c = a.0.is_nan() || b.0.is_nan();
  144. Some(c as i32)
  145. },
  146. "builtins::float::cmp::__unordsf2(a, b)",
  147. );
  148. gen(
  149. |(a, b): (MyF64, MyF64)| {
  150. let c = a.0.is_nan() || b.0.is_nan();
  151. Some(c as i32)
  152. },
  153. "builtins::float::cmp::__unorddf2(a, b)",
  154. );
  155. if target_arch_arm {
  156. gen(
  157. |(a, b): (MyF32, MyF32)| {
  158. if a.0.is_nan() || b.0.is_nan() {
  159. return None;
  160. }
  161. let c = (a.0 <= b.0) as i32;
  162. Some(c)
  163. },
  164. "builtins::float::cmp::__aeabi_fcmple(a, b)",
  165. );
  166. gen(
  167. |(a, b): (MyF32, MyF32)| {
  168. if a.0.is_nan() || b.0.is_nan() {
  169. return None;
  170. }
  171. let c = (a.0 >= b.0) as i32;
  172. Some(c)
  173. },
  174. "builtins::float::cmp::__aeabi_fcmpge(a, b)",
  175. );
  176. gen(
  177. |(a, b): (MyF32, MyF32)| {
  178. if a.0.is_nan() || b.0.is_nan() {
  179. return None;
  180. }
  181. let c = (a.0 == b.0) as i32;
  182. Some(c)
  183. },
  184. "builtins::float::cmp::__aeabi_fcmpeq(a, b)",
  185. );
  186. gen(
  187. |(a, b): (MyF32, MyF32)| {
  188. if a.0.is_nan() || b.0.is_nan() {
  189. return None;
  190. }
  191. let c = (a.0 < b.0) as i32;
  192. Some(c)
  193. },
  194. "builtins::float::cmp::__aeabi_fcmplt(a, b)",
  195. );
  196. gen(
  197. |(a, b): (MyF32, MyF32)| {
  198. if a.0.is_nan() || b.0.is_nan() {
  199. return None;
  200. }
  201. let c = (a.0 > b.0) as i32;
  202. Some(c)
  203. },
  204. "builtins::float::cmp::__aeabi_fcmpgt(a, b)",
  205. );
  206. gen(
  207. |(a, b): (MyF64, MyF64)| {
  208. if a.0.is_nan() || b.0.is_nan() {
  209. return None;
  210. }
  211. let c = (a.0 <= b.0) as i32;
  212. Some(c)
  213. },
  214. "builtins::float::cmp::__aeabi_dcmple(a, b)",
  215. );
  216. gen(
  217. |(a, b): (MyF64, MyF64)| {
  218. if a.0.is_nan() || b.0.is_nan() {
  219. return None;
  220. }
  221. let c = (a.0 >= b.0) as i32;
  222. Some(c)
  223. },
  224. "builtins::float::cmp::__aeabi_dcmpge(a, b)",
  225. );
  226. gen(
  227. |(a, b): (MyF64, MyF64)| {
  228. if a.0.is_nan() || b.0.is_nan() {
  229. return None;
  230. }
  231. let c = (a.0 == b.0) as i32;
  232. Some(c)
  233. },
  234. "builtins::float::cmp::__aeabi_dcmpeq(a, b)",
  235. );
  236. gen(
  237. |(a, b): (MyF64, MyF64)| {
  238. if a.0.is_nan() || b.0.is_nan() {
  239. return None;
  240. }
  241. let c = (a.0 < b.0) as i32;
  242. Some(c)
  243. },
  244. "builtins::float::cmp::__aeabi_dcmplt(a, b)",
  245. );
  246. gen(
  247. |(a, b): (MyF64, MyF64)| {
  248. if a.0.is_nan() || b.0.is_nan() {
  249. return None;
  250. }
  251. let c = (a.0 > b.0) as i32;
  252. Some(c)
  253. },
  254. "builtins::float::cmp::__aeabi_dcmpgt(a, b)",
  255. );
  256. gen(
  257. |(a, b): (LargeF32, LargeF32)| {
  258. if a.0.is_nan() || b.0.is_nan() {
  259. return None;
  260. }
  261. Some((a.0 >= b.0) as i32)
  262. },
  263. "builtins::float::cmp::__gesf2vfp(a, b)",
  264. );
  265. gen(
  266. |(a, b): (MyF64, MyF64)| {
  267. if a.0.is_nan() || b.0.is_nan() {
  268. return None;
  269. }
  270. Some((a.0 >= b.0) as i32)
  271. },
  272. "builtins::float::cmp::__gedf2vfp(a, b)",
  273. );
  274. gen(
  275. |(a, b): (LargeF32, LargeF32)| {
  276. if a.0.is_nan() || b.0.is_nan() {
  277. return None;
  278. }
  279. Some((a.0 > b.0) as i32)
  280. },
  281. "builtins::float::cmp::__gtsf2vfp(a, b)",
  282. );
  283. gen(
  284. |(a, b): (MyF64, MyF64)| {
  285. if a.0.is_nan() || b.0.is_nan() {
  286. return None;
  287. }
  288. Some((a.0 > b.0) as i32)
  289. },
  290. "builtins::float::cmp::__gtdf2vfp(a, b)",
  291. );
  292. gen(
  293. |(a, b): (LargeF32, LargeF32)| {
  294. if a.0.is_nan() || b.0.is_nan() {
  295. return None;
  296. }
  297. Some((a.0 < b.0) as i32)
  298. },
  299. "builtins::float::cmp::__ltsf2vfp(a, b)",
  300. );
  301. gen(
  302. |(a, b): (MyF64, MyF64)| {
  303. if a.0.is_nan() || b.0.is_nan() {
  304. return None;
  305. }
  306. Some((a.0 < b.0) as i32)
  307. },
  308. "builtins::float::cmp::__ltdf2vfp(a, b)",
  309. );
  310. gen(
  311. |(a, b): (LargeF32, LargeF32)| {
  312. if a.0.is_nan() || b.0.is_nan() {
  313. return None;
  314. }
  315. Some((a.0 <= b.0) as i32)
  316. },
  317. "builtins::float::cmp::__lesf2vfp(a, b)",
  318. );
  319. gen(
  320. |(a, b): (MyF64, MyF64)| {
  321. if a.0.is_nan() || b.0.is_nan() {
  322. return None;
  323. }
  324. Some((a.0 <= b.0) as i32)
  325. },
  326. "builtins::float::cmp::__ledf2vfp(a, b)",
  327. );
  328. gen(
  329. |(a, b): (LargeF32, LargeF32)| {
  330. if a.0.is_nan() || b.0.is_nan() {
  331. return None;
  332. }
  333. Some((a.0 != b.0) as i32)
  334. },
  335. "builtins::float::cmp::__nesf2vfp(a, b)",
  336. );
  337. gen(
  338. |(a, b): (MyF64, MyF64)| {
  339. if a.0.is_nan() || b.0.is_nan() {
  340. return None;
  341. }
  342. Some((a.0 != b.0) as i32)
  343. },
  344. "builtins::float::cmp::__nedf2vfp(a, b)",
  345. );
  346. gen(
  347. |(a, b): (LargeF32, LargeF32)| {
  348. if a.0.is_nan() || b.0.is_nan() {
  349. return None;
  350. }
  351. Some((a.0 == b.0) as i32)
  352. },
  353. "builtins::float::cmp::__eqsf2vfp(a, b)",
  354. );
  355. gen(
  356. |(a, b): (MyF64, MyF64)| {
  357. if a.0.is_nan() || b.0.is_nan() {
  358. return None;
  359. }
  360. Some((a.0 == b.0) as i32)
  361. },
  362. "builtins::float::cmp::__eqdf2vfp(a, b)",
  363. );
  364. }
  365. // float/extend.rs
  366. gen(
  367. |a: MyF32| {
  368. if a.0.is_nan() {
  369. return None;
  370. }
  371. Some(f64::from(a.0))
  372. },
  373. "builtins::float::extend::__extendsfdf2(a)",
  374. );
  375. if target_arch_arm {
  376. gen(
  377. |a: LargeF32| {
  378. if a.0.is_nan() {
  379. return None;
  380. }
  381. Some(f64::from(a.0))
  382. },
  383. "builtins::float::extend::__extendsfdf2vfp(a)",
  384. );
  385. }
  386. // float/conv.rs
  387. gen(
  388. |a: MyF64| i64::cast(a.0),
  389. "builtins::float::conv::__fixdfdi(a)",
  390. );
  391. gen(
  392. |a: MyF64| i32::cast(a.0),
  393. "builtins::float::conv::__fixdfsi(a)",
  394. );
  395. gen(
  396. |a: MyF32| i64::cast(a.0),
  397. "builtins::float::conv::__fixsfdi(a)",
  398. );
  399. gen(
  400. |a: MyF32| i32::cast(a.0),
  401. "builtins::float::conv::__fixsfsi(a)",
  402. );
  403. gen(
  404. |a: MyF32| i128::cast(a.0),
  405. "builtins::float::conv::__fixsfti(a)",
  406. );
  407. gen(
  408. |a: MyF64| i128::cast(a.0),
  409. "builtins::float::conv::__fixdfti(a)",
  410. );
  411. gen(
  412. |a: MyF64| u64::cast(a.0),
  413. "builtins::float::conv::__fixunsdfdi(a)",
  414. );
  415. gen(
  416. |a: MyF64| u32::cast(a.0),
  417. "builtins::float::conv::__fixunsdfsi(a)",
  418. );
  419. gen(
  420. |a: MyF32| u64::cast(a.0),
  421. "builtins::float::conv::__fixunssfdi(a)",
  422. );
  423. gen(
  424. |a: MyF32| u32::cast(a.0),
  425. "builtins::float::conv::__fixunssfsi(a)",
  426. );
  427. gen(
  428. |a: MyF32| u128::cast(a.0),
  429. "builtins::float::conv::__fixunssfti(a)",
  430. );
  431. gen(
  432. |a: MyF64| u128::cast(a.0),
  433. "builtins::float::conv::__fixunsdfti(a)",
  434. );
  435. gen(
  436. |a: MyI64| Some(a.0 as f64),
  437. "builtins::float::conv::__floatdidf(a)",
  438. );
  439. gen(
  440. |a: MyI32| Some(a.0 as f64),
  441. "builtins::float::conv::__floatsidf(a)",
  442. );
  443. gen(
  444. |a: MyI32| Some(a.0 as f32),
  445. "builtins::float::conv::__floatsisf(a)",
  446. );
  447. gen(
  448. |a: MyU64| Some(a.0 as f64),
  449. "builtins::float::conv::__floatundidf(a)",
  450. );
  451. gen(
  452. |a: MyU32| Some(a.0 as f64),
  453. "builtins::float::conv::__floatunsidf(a)",
  454. );
  455. gen(
  456. |a: MyU32| Some(a.0 as f32),
  457. "builtins::float::conv::__floatunsisf(a)",
  458. );
  459. gen(
  460. |a: MyU128| Some(a.0 as f32),
  461. "builtins::float::conv::__floatuntisf(a)",
  462. );
  463. if !target_arch_mips {
  464. gen(
  465. |a: MyI128| Some(a.0 as f32),
  466. "builtins::float::conv::__floattisf(a)",
  467. );
  468. gen(
  469. |a: MyI128| Some(a.0 as f64),
  470. "builtins::float::conv::__floattidf(a)",
  471. );
  472. gen(
  473. |a: MyU128| Some(a.0 as f64),
  474. "builtins::float::conv::__floatuntidf(a)",
  475. );
  476. }
  477. // float/pow.rs
  478. gen(
  479. |(a, b): (MyF64, MyI32)| {
  480. let c = a.0.powi(b.0);
  481. if a.0.is_nan() || c.is_nan() {
  482. None
  483. } else {
  484. Some(c)
  485. }
  486. },
  487. "builtins::float::pow::__powidf2(a, b)",
  488. );
  489. gen(
  490. |(a, b): (MyF32, MyI32)| {
  491. let c = a.0.powi(b.0);
  492. if a.0.is_nan() || c.is_nan() {
  493. None
  494. } else {
  495. Some(c)
  496. }
  497. },
  498. "builtins::float::pow::__powisf2(a, b)",
  499. );
  500. // float/sub.rs
  501. gen(
  502. |(a, b): (MyF64, MyF64)| {
  503. let c = a.0 - b.0;
  504. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  505. None
  506. } else {
  507. Some(c)
  508. }
  509. },
  510. "builtins::float::sub::__subdf3(a, b)",
  511. );
  512. gen(
  513. |(a, b): (MyF32, MyF32)| {
  514. let c = a.0 - b.0;
  515. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  516. None
  517. } else {
  518. Some(c)
  519. }
  520. },
  521. "builtins::float::sub::__subsf3(a, b)",
  522. );
  523. if target_arch_arm {
  524. gen(
  525. |(a, b): (MyF64, MyF64)| {
  526. let c = a.0 - b.0;
  527. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  528. None
  529. } else {
  530. Some(c)
  531. }
  532. },
  533. "builtins::float::sub::__subdf3vfp(a, b)",
  534. );
  535. gen(
  536. |(a, b): (LargeF32, LargeF32)| {
  537. let c = a.0 - b.0;
  538. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  539. None
  540. } else {
  541. Some(c)
  542. }
  543. },
  544. "builtins::float::sub::__subsf3vfp(a, b)",
  545. );
  546. }
  547. // float/mul.rs
  548. gen(
  549. |(a, b): (MyF64, MyF64)| {
  550. let c = a.0 * b.0;
  551. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  552. None
  553. } else {
  554. Some(c)
  555. }
  556. },
  557. "builtins::float::mul::__muldf3(a, b)",
  558. );
  559. gen(
  560. |(a, b): (LargeF32, LargeF32)| {
  561. let c = a.0 * b.0;
  562. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  563. None
  564. } else {
  565. Some(c)
  566. }
  567. },
  568. "builtins::float::mul::__mulsf3(a, b)",
  569. );
  570. if target_arch_arm {
  571. gen(
  572. |(a, b): (MyF64, MyF64)| {
  573. let c = a.0 * b.0;
  574. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  575. None
  576. } else {
  577. Some(c)
  578. }
  579. },
  580. "builtins::float::mul::__muldf3vfp(a, b)",
  581. );
  582. gen(
  583. |(a, b): (LargeF32, LargeF32)| {
  584. let c = a.0 * b.0;
  585. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  586. None
  587. } else {
  588. Some(c)
  589. }
  590. },
  591. "builtins::float::mul::__mulsf3vfp(a, b)",
  592. );
  593. }
  594. // float/div.rs
  595. gen(
  596. |(a, b): (MyF64, MyF64)| {
  597. if b.0 == 0.0 {
  598. return None;
  599. }
  600. let c = a.0 / b.0;
  601. if a.0.is_nan()
  602. || b.0.is_nan()
  603. || c.is_nan()
  604. || c.abs() <= unsafe { mem::transmute(4503599627370495u64) }
  605. {
  606. None
  607. } else {
  608. Some(c)
  609. }
  610. },
  611. "builtins::float::div::__divdf3(a, b)",
  612. );
  613. gen(
  614. |(a, b): (LargeF32, LargeF32)| {
  615. if b.0 == 0.0 {
  616. return None;
  617. }
  618. let c = a.0 / b.0;
  619. if a.0.is_nan()
  620. || b.0.is_nan()
  621. || c.is_nan()
  622. || c.abs() <= unsafe { mem::transmute(16777215u32) }
  623. {
  624. None
  625. } else {
  626. Some(c)
  627. }
  628. },
  629. "builtins::float::div::__divsf3(a, b)",
  630. );
  631. if target_arch_arm {
  632. gen(
  633. |(a, b): (MyF64, MyF64)| {
  634. if b.0 == 0.0 {
  635. return None;
  636. }
  637. let c = a.0 / b.0;
  638. if a.0.is_nan()
  639. || b.0.is_nan()
  640. || c.is_nan()
  641. || c.abs() <= unsafe { mem::transmute(4503599627370495u64) }
  642. {
  643. None
  644. } else {
  645. Some(c)
  646. }
  647. },
  648. "builtins::float::div::__divdf3vfp(a, b)",
  649. );
  650. gen(
  651. |(a, b): (LargeF32, LargeF32)| {
  652. if b.0 == 0.0 {
  653. return None;
  654. }
  655. let c = a.0 / b.0;
  656. if a.0.is_nan()
  657. || b.0.is_nan()
  658. || c.is_nan()
  659. || c.abs() <= unsafe { mem::transmute(16777215u32) }
  660. {
  661. None
  662. } else {
  663. Some(c)
  664. }
  665. },
  666. "builtins::float::div::__divsf3vfp(a, b)",
  667. );
  668. }
  669. // int/addsub.rs
  670. gen(
  671. |(a, b): (MyU128, MyU128)| Some(a.0.wrapping_add(b.0)),
  672. "builtins::int::addsub::__rust_u128_add(a, b)",
  673. );
  674. gen(
  675. |(a, b): (MyI128, MyI128)| Some(a.0.wrapping_add(b.0)),
  676. "builtins::int::addsub::__rust_i128_add(a, b)",
  677. );
  678. gen(
  679. |(a, b): (MyU128, MyU128)| Some(a.0.overflowing_add(b.0)),
  680. "builtins::int::addsub::__rust_u128_addo(a, b)",
  681. );
  682. gen(
  683. |(a, b): (MyI128, MyI128)| Some(a.0.overflowing_add(b.0)),
  684. "builtins::int::addsub::__rust_i128_addo(a, b)",
  685. );
  686. gen(
  687. |(a, b): (MyU128, MyU128)| Some(a.0.wrapping_sub(b.0)),
  688. "builtins::int::addsub::__rust_u128_sub(a, b)",
  689. );
  690. gen(
  691. |(a, b): (MyI128, MyI128)| Some(a.0.wrapping_sub(b.0)),
  692. "builtins::int::addsub::__rust_i128_sub(a, b)",
  693. );
  694. gen(
  695. |(a, b): (MyU128, MyU128)| Some(a.0.overflowing_sub(b.0)),
  696. "builtins::int::addsub::__rust_u128_subo(a, b)",
  697. );
  698. gen(
  699. |(a, b): (MyI128, MyI128)| Some(a.0.overflowing_sub(b.0)),
  700. "builtins::int::addsub::__rust_i128_subo(a, b)",
  701. );
  702. // int/mul.rs
  703. gen(
  704. |(a, b): (MyU64, MyU64)| Some(a.0.wrapping_mul(b.0)),
  705. "builtins::int::mul::__muldi3(a, b)",
  706. );
  707. gen(
  708. |(a, b): (MyI64, MyI64)| Some(a.0.overflowing_mul(b.0)),
  709. "{
  710. let mut o = 2;
  711. let c = builtins::int::mul::__mulodi4(a, b, &mut o);
  712. (c, match o { 0 => false, 1 => true, _ => panic!() })
  713. }",
  714. );
  715. gen(
  716. |(a, b): (MyI32, MyI32)| Some(a.0.overflowing_mul(b.0)),
  717. "{
  718. let mut o = 2;
  719. let c = builtins::int::mul::__mulosi4(a, b, &mut o);
  720. (c, match o { 0 => false, 1 => true, _ => panic!() })
  721. }",
  722. );
  723. gen(
  724. |(a, b): (MyI128, MyI128)| Some(a.0.wrapping_mul(b.0)),
  725. "builtins::int::mul::__multi3(a, b)",
  726. );
  727. gen(
  728. |(a, b): (MyI128, MyI128)| Some(a.0.overflowing_mul(b.0)),
  729. "{
  730. let mut o = 2;
  731. let c = builtins::int::mul::__muloti4(a, b, &mut o);
  732. (c, match o { 0 => false, 1 => true, _ => panic!() })
  733. }",
  734. );
  735. // int/sdiv.rs
  736. gen(
  737. |(a, b): (MyI64, MyI64)| {
  738. if b.0 == 0 {
  739. None
  740. } else {
  741. Some(a.0 / b.0)
  742. }
  743. },
  744. "builtins::int::sdiv::__divdi3(a, b)",
  745. );
  746. gen(
  747. |(a, b): (MyI64, MyI64)| {
  748. if b.0 == 0 {
  749. None
  750. } else {
  751. Some((a.0 / b.0, a.0 % b.0))
  752. }
  753. },
  754. "{
  755. let mut r = 0;
  756. (builtins::int::sdiv::__divmoddi4(a, b, &mut r), r)
  757. }",
  758. );
  759. gen(
  760. |(a, b): (MyI32, MyI32)| {
  761. if b.0 == 0 {
  762. None
  763. } else {
  764. Some((a.0 / b.0, a.0 % b.0))
  765. }
  766. },
  767. "{
  768. let mut r = 0;
  769. (builtins::int::sdiv::__divmodsi4(a, b, &mut r), r)
  770. }",
  771. );
  772. gen(
  773. |(a, b): (MyI32, MyI32)| {
  774. if b.0 == 0 {
  775. None
  776. } else {
  777. Some(a.0 / b.0)
  778. }
  779. },
  780. "builtins::int::sdiv::__divsi3(a, b)",
  781. );
  782. gen(
  783. |(a, b): (MyI32, MyI32)| {
  784. if b.0 == 0 {
  785. None
  786. } else {
  787. Some(a.0 % b.0)
  788. }
  789. },
  790. "builtins::int::sdiv::__modsi3(a, b)",
  791. );
  792. gen(
  793. |(a, b): (MyI64, MyI64)| {
  794. if b.0 == 0 {
  795. None
  796. } else {
  797. Some(a.0 % b.0)
  798. }
  799. },
  800. "builtins::int::sdiv::__moddi3(a, b)",
  801. );
  802. gen(
  803. |(a, b): (MyI128, MyI128)| {
  804. if b.0 == 0 {
  805. None
  806. } else {
  807. Some(a.0 / b.0)
  808. }
  809. },
  810. "builtins::int::sdiv::__divti3(a, b)",
  811. );
  812. gen(
  813. |(a, b): (MyI128, MyI128)| {
  814. if b.0 == 0 {
  815. None
  816. } else {
  817. Some(a.0 % b.0)
  818. }
  819. },
  820. "builtins::int::sdiv::__modti3(a, b)",
  821. );
  822. // int/shift.rs
  823. gen(
  824. |(a, b): (MyU64, MyU32)| Some(a.0 << (b.0 % 64)),
  825. "builtins::int::shift::__ashldi3(a, b % 64)",
  826. );
  827. gen(
  828. |(a, b): (MyU128, MyU32)| Some(a.0 << (b.0 % 128)),
  829. "builtins::int::shift::__ashlti3(a, b % 128)",
  830. );
  831. gen(
  832. |(a, b): (MyI64, MyU32)| Some(a.0 >> (b.0 % 64)),
  833. "builtins::int::shift::__ashrdi3(a, b % 64)",
  834. );
  835. gen(
  836. |(a, b): (MyI128, MyU32)| Some(a.0 >> (b.0 % 128)),
  837. "builtins::int::shift::__ashrti3(a, b % 128)",
  838. );
  839. gen(
  840. |(a, b): (MyU64, MyU32)| Some(a.0 >> (b.0 % 64)),
  841. "builtins::int::shift::__lshrdi3(a, b % 64)",
  842. );
  843. gen(
  844. |(a, b): (MyU128, MyU32)| Some(a.0 >> (b.0 % 128)),
  845. "builtins::int::shift::__lshrti3(a, b % 128)",
  846. );
  847. // int/udiv.rs
  848. gen(
  849. |(a, b): (MyU64, MyU64)| {
  850. if b.0 == 0 {
  851. None
  852. } else {
  853. Some(a.0 / b.0)
  854. }
  855. },
  856. "builtins::int::udiv::__udivdi3(a, b)",
  857. );
  858. gen(
  859. |(a, b): (MyU64, MyU64)| {
  860. if b.0 == 0 {
  861. None
  862. } else {
  863. Some((a.0 / b.0, a.0 % b.0))
  864. }
  865. },
  866. "{
  867. let mut r = 0;
  868. (builtins::int::udiv::__udivmoddi4(a, b, Some(&mut r)), r)
  869. }",
  870. );
  871. gen(
  872. |(a, b): (MyU32, MyU32)| {
  873. if b.0 == 0 {
  874. None
  875. } else {
  876. Some((a.0 / b.0, a.0 % b.0))
  877. }
  878. },
  879. "{
  880. let mut r = 0;
  881. (builtins::int::udiv::__udivmodsi4(a, b, Some(&mut r)), r)
  882. }",
  883. );
  884. gen(
  885. |(a, b): (MyU32, MyU32)| {
  886. if b.0 == 0 {
  887. None
  888. } else {
  889. Some(a.0 / b.0)
  890. }
  891. },
  892. "builtins::int::udiv::__udivsi3(a, b)",
  893. );
  894. gen(
  895. |(a, b): (MyU32, MyU32)| {
  896. if b.0 == 0 {
  897. None
  898. } else {
  899. Some(a.0 % b.0)
  900. }
  901. },
  902. "builtins::int::udiv::__umodsi3(a, b)",
  903. );
  904. gen(
  905. |(a, b): (MyU64, MyU64)| {
  906. if b.0 == 0 {
  907. None
  908. } else {
  909. Some(a.0 % b.0)
  910. }
  911. },
  912. "builtins::int::udiv::__umoddi3(a, b)",
  913. );
  914. gen(
  915. |(a, b): (MyU128, MyU128)| {
  916. if b.0 == 0 {
  917. None
  918. } else {
  919. Some(a.0 / b.0)
  920. }
  921. },
  922. "builtins::int::udiv::__udivti3(a, b)",
  923. );
  924. gen(
  925. |(a, b): (MyU128, MyU128)| {
  926. if b.0 == 0 {
  927. None
  928. } else {
  929. Some(a.0 % b.0)
  930. }
  931. },
  932. "builtins::int::udiv::__umodti3(a, b)",
  933. );
  934. gen(
  935. |(a, b): (MyU128, MyU128)| {
  936. if b.0 == 0 {
  937. None
  938. } else {
  939. Some((a.0 / b.0, a.0 % b.0))
  940. }
  941. },
  942. "{
  943. let mut r = 0;
  944. (builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r)
  945. }",
  946. );
  947. }
  948. macro_rules! gen_float {
  949. ($name:ident,
  950. $fty:ident,
  951. $uty:ident,
  952. $bits:expr,
  953. $significand_bits:expr) => {
  954. pub fn $name<R>(rng: &mut R) -> $fty
  955. where
  956. R: Rng + ?Sized,
  957. {
  958. const BITS: u8 = $bits;
  959. const SIGNIFICAND_BITS: u8 = $significand_bits;
  960. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  961. const SIGN_MASK: $uty = (1 << (BITS - 1));
  962. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  963. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  964. unsafe {
  965. mem::transmute(
  966. ((sign as $uty) << (BITS - 1))
  967. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  968. | (significand & SIGNIFICAND_MASK),
  969. )
  970. }
  971. }
  972. if rng.gen_range(0, 10) == 1 {
  973. // Special values
  974. *[
  975. -0.0,
  976. 0.0,
  977. ::std::$fty::MIN,
  978. ::std::$fty::MIN_POSITIVE,
  979. ::std::$fty::MAX,
  980. ::std::$fty::NAN,
  981. ::std::$fty::INFINITY,
  982. -::std::$fty::INFINITY,
  983. ]
  984. .choose(rng)
  985. .unwrap()
  986. } else if rng.gen_range(0, 10) == 1 {
  987. // NaN patterns
  988. mk_f32(rng.gen(), rng.gen(), 0)
  989. } else if rng.gen() {
  990. // Denormalized
  991. mk_f32(rng.gen(), 0, rng.gen())
  992. } else {
  993. // Random anything
  994. mk_f32(rng.gen(), rng.gen(), rng.gen())
  995. }
  996. }
  997. };
  998. }
  999. gen_float!(gen_f32, f32, u32, 32, 23);
  1000. gen_float!(gen_f64, f64, u64, 64, 52);
  1001. macro_rules! gen_large_float {
  1002. ($name:ident,
  1003. $fty:ident,
  1004. $uty:ident,
  1005. $bits:expr,
  1006. $significand_bits:expr) => {
  1007. pub fn $name<R>(rng: &mut R) -> $fty
  1008. where
  1009. R: Rng + ?Sized,
  1010. {
  1011. const BITS: u8 = $bits;
  1012. const SIGNIFICAND_BITS: u8 = $significand_bits;
  1013. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  1014. const SIGN_MASK: $uty = (1 << (BITS - 1));
  1015. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  1016. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  1017. unsafe {
  1018. mem::transmute(
  1019. ((sign as $uty) << (BITS - 1))
  1020. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  1021. | (significand & SIGNIFICAND_MASK),
  1022. )
  1023. }
  1024. }
  1025. if rng.gen_range(0, 10) == 1 {
  1026. // Special values
  1027. *[
  1028. -0.0,
  1029. 0.0,
  1030. ::std::$fty::MIN,
  1031. ::std::$fty::MIN_POSITIVE,
  1032. ::std::$fty::MAX,
  1033. ::std::$fty::NAN,
  1034. ::std::$fty::INFINITY,
  1035. -::std::$fty::INFINITY,
  1036. ]
  1037. .choose(rng)
  1038. .unwrap()
  1039. } else if rng.gen_range(0, 10) == 1 {
  1040. // NaN patterns
  1041. mk_f32(rng.gen(), rng.gen(), 0)
  1042. } else if rng.gen() {
  1043. // Denormalized
  1044. mk_f32(rng.gen(), 0, rng.gen())
  1045. } else {
  1046. // Random anything
  1047. rng.gen::<$fty>()
  1048. }
  1049. }
  1050. };
  1051. }
  1052. gen_large_float!(gen_large_f32, f32, u32, 32, 23);
  1053. gen_large_float!(gen_large_f64, f64, u64, 64, 52);
  1054. trait TestInput: Hash + Eq + fmt::Debug {
  1055. fn ty_name() -> String;
  1056. fn generate_lets(container: &str, cnt: &mut u8) -> String;
  1057. fn generate_static(&self, dst: &mut String);
  1058. }
  1059. trait TestOutput {
  1060. fn ty_name() -> String;
  1061. fn generate_static(&self, dst: &mut String);
  1062. fn generate_expr(container: &str) -> String;
  1063. }
  1064. fn gen<F, A, R>(mut generate: F, test: &str)
  1065. where
  1066. F: FnMut(A) -> Option<R>,
  1067. A: TestInput + Copy,
  1068. R: TestOutput,
  1069. rand::distributions::Standard: rand::distributions::Distribution<A>,
  1070. {
  1071. let rng = &mut rand::thread_rng();
  1072. let testname = test.split("::").last().unwrap().split("(").next().unwrap();
  1073. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  1074. let out_file = out_dir.join("generated.rs");
  1075. let mut testcases = HashMap::new();
  1076. let mut n = NTESTS;
  1077. while n > 0 {
  1078. let input: A = rng.gen();
  1079. if testcases.contains_key(&input) {
  1080. continue;
  1081. }
  1082. let output = match generate(input) {
  1083. Some(o) => o,
  1084. None => continue,
  1085. };
  1086. testcases.insert(input, output);
  1087. n -= 1;
  1088. }
  1089. let mut contents = String::new();
  1090. contents.push_str(&format!("mod {} {{\nuse super::*;\n", testname));
  1091. contents.push_str("#[test]\n");
  1092. contents.push_str("fn test() {\n");
  1093. contents.push_str(&format!(
  1094. "static TESTS: [({}, {}); {}] = [\n",
  1095. A::ty_name(),
  1096. R::ty_name(),
  1097. NTESTS
  1098. ));
  1099. for (input, output) in testcases {
  1100. contents.push_str(" (");
  1101. input.generate_static(&mut contents);
  1102. contents.push_str(", ");
  1103. output.generate_static(&mut contents);
  1104. contents.push_str("),\n");
  1105. }
  1106. contents.push_str("];\n");
  1107. contents.push_str(&format!(
  1108. r#"
  1109. for &(inputs, output) in TESTS.iter() {{
  1110. {}
  1111. assert_eq!({}, {}, "inputs {{:?}}", inputs)
  1112. }}
  1113. "#,
  1114. A::generate_lets("inputs", &mut 0),
  1115. R::generate_expr("output"),
  1116. test,
  1117. ));
  1118. contents.push_str("\n}\n");
  1119. contents.push_str("\n}\n");
  1120. OpenOptions::new()
  1121. .write(true)
  1122. .append(true)
  1123. .create(true)
  1124. .open(out_file)
  1125. .unwrap()
  1126. .write_all(contents.as_bytes())
  1127. .unwrap();
  1128. }
  1129. macro_rules! my_float {
  1130. ($(struct $name:ident($inner:ident) = $gen:ident;)*) => ($(
  1131. #[derive(Debug, Clone, Copy)]
  1132. struct $name($inner);
  1133. impl TestInput for $name {
  1134. fn ty_name() -> String {
  1135. format!("u{}", &stringify!($inner)[1..])
  1136. }
  1137. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1138. let me = *cnt;
  1139. *cnt += 1;
  1140. format!("let {} = {}::from_bits({});\n",
  1141. (b'a' + me) as char,
  1142. stringify!($inner),
  1143. container)
  1144. }
  1145. fn generate_static(&self, dst: &mut String) {
  1146. write!(dst, "{}", self.0.to_bits()).unwrap();
  1147. }
  1148. }
  1149. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1150. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1151. $name($gen(r))
  1152. }
  1153. }
  1154. impl Hash for $name {
  1155. fn hash<H: Hasher>(&self, h: &mut H) {
  1156. self.0.to_bits().hash(h)
  1157. }
  1158. }
  1159. impl PartialEq for $name {
  1160. fn eq(&self, other: &$name) -> bool {
  1161. self.0.to_bits() == other.0.to_bits()
  1162. }
  1163. }
  1164. impl Eq for $name {}
  1165. )*)
  1166. }
  1167. my_float! {
  1168. struct MyF64(f64) = gen_f64;
  1169. struct LargeF64(f64) = gen_large_f64;
  1170. struct MyF32(f32) = gen_f32;
  1171. struct LargeF32(f32) = gen_large_f32;
  1172. }
  1173. macro_rules! my_integer {
  1174. ($(struct $name:ident($inner:ident);)*) => ($(
  1175. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
  1176. struct $name($inner);
  1177. impl TestInput for $name {
  1178. fn ty_name() -> String {
  1179. stringify!($inner).to_string()
  1180. }
  1181. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1182. let me = *cnt;
  1183. *cnt += 1;
  1184. format!("let {} = {};\n",
  1185. (b'a' + me) as char,
  1186. container)
  1187. }
  1188. fn generate_static(&self, dst: &mut String) {
  1189. write!(dst, "{}", self.0).unwrap();
  1190. }
  1191. }
  1192. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1193. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1194. let bits = (0 as $inner).count_zeros();
  1195. let mut mk = || {
  1196. if r.gen_range(0, 10) == 1 {
  1197. *[
  1198. ::std::$inner::MAX >> (bits / 2),
  1199. 0,
  1200. ::std::$inner::MIN >> (bits / 2),
  1201. ].choose(r).unwrap()
  1202. } else {
  1203. r.gen::<$inner>()
  1204. }
  1205. };
  1206. let a = mk();
  1207. let b = mk();
  1208. $name((a << (bits / 2)) | (b & (!0 << (bits / 2))))
  1209. }
  1210. }
  1211. )*)
  1212. }
  1213. my_integer! {
  1214. struct MyI32(i32);
  1215. struct MyI64(i64);
  1216. struct MyI128(i128);
  1217. struct MyU32(u32);
  1218. struct MyU64(u64);
  1219. struct MyU128(u128);
  1220. }
  1221. impl<A, B> TestInput for (A, B)
  1222. where
  1223. A: TestInput,
  1224. B: TestInput,
  1225. {
  1226. fn ty_name() -> String {
  1227. format!("({}, {})", A::ty_name(), B::ty_name())
  1228. }
  1229. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1230. format!(
  1231. "{}{}",
  1232. A::generate_lets(&format!("{}.0", container), cnt),
  1233. B::generate_lets(&format!("{}.1", container), cnt)
  1234. )
  1235. }
  1236. fn generate_static(&self, dst: &mut String) {
  1237. dst.push_str("(");
  1238. self.0.generate_static(dst);
  1239. dst.push_str(", ");
  1240. self.1.generate_static(dst);
  1241. dst.push_str(")");
  1242. }
  1243. }
  1244. impl TestOutput for f64 {
  1245. fn ty_name() -> String {
  1246. "u64".to_string()
  1247. }
  1248. fn generate_static(&self, dst: &mut String) {
  1249. write!(dst, "{}", self.to_bits()).unwrap();
  1250. }
  1251. fn generate_expr(container: &str) -> String {
  1252. format!("f64::from_bits({})", container)
  1253. }
  1254. }
  1255. impl TestOutput for f32 {
  1256. fn ty_name() -> String {
  1257. "u32".to_string()
  1258. }
  1259. fn generate_static(&self, dst: &mut String) {
  1260. write!(dst, "{}", self.to_bits()).unwrap();
  1261. }
  1262. fn generate_expr(container: &str) -> String {
  1263. format!("f32::from_bits({})", container)
  1264. }
  1265. }
  1266. macro_rules! plain_test_output {
  1267. ($($i:tt)*) => ($(
  1268. impl TestOutput for $i {
  1269. fn ty_name() -> String {
  1270. stringify!($i).to_string()
  1271. }
  1272. fn generate_static(&self, dst: &mut String) {
  1273. write!(dst, "{}", self).unwrap();
  1274. }
  1275. fn generate_expr(container: &str) -> String {
  1276. container.to_string()
  1277. }
  1278. }
  1279. )*)
  1280. }
  1281. plain_test_output!(i32 i64 i128 u32 u64 u128 bool);
  1282. impl<A, B> TestOutput for (A, B)
  1283. where
  1284. A: TestOutput,
  1285. B: TestOutput,
  1286. {
  1287. fn ty_name() -> String {
  1288. format!("({}, {})", A::ty_name(), B::ty_name())
  1289. }
  1290. fn generate_static(&self, dst: &mut String) {
  1291. dst.push_str("(");
  1292. self.0.generate_static(dst);
  1293. dst.push_str(", ");
  1294. self.1.generate_static(dst);
  1295. dst.push_str(")");
  1296. }
  1297. fn generate_expr(container: &str) -> String {
  1298. container.to_string()
  1299. }
  1300. }
  1301. trait FromFloat<T>: Sized {
  1302. fn cast(src: T) -> Option<Self>;
  1303. }
  1304. macro_rules! from_float {
  1305. ($($src:ident => $($dst:ident),+);+;) => {
  1306. $(
  1307. $(
  1308. impl FromFloat<$src> for $dst {
  1309. fn cast(src: $src) -> Option<$dst> {
  1310. use std::{$dst, $src};
  1311. if src.is_nan() ||
  1312. src.is_infinite() ||
  1313. src < std::$dst::MIN as $src ||
  1314. src > std::$dst::MAX as $src
  1315. {
  1316. None
  1317. } else {
  1318. Some(src as $dst)
  1319. }
  1320. }
  1321. }
  1322. )+
  1323. )+
  1324. }
  1325. }
  1326. from_float! {
  1327. f32 => i32, i64, i128, u32, u64, u128;
  1328. f64 => i32, i64, i128, u32, u64, u128;
  1329. }