build.rs 35 KB

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