build.rs 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162
  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/conv.rs
  323. gen(|a: MyF64| i64(a.0).ok(),
  324. "builtins::float::conv::__fixdfdi(a)");
  325. gen(|a: MyF64| i32(a.0).ok(),
  326. "builtins::float::conv::__fixdfsi(a)");
  327. gen(|a: MyF32| i64(a.0).ok(),
  328. "builtins::float::conv::__fixsfdi(a)");
  329. gen(|a: MyF32| i32(a.0).ok(),
  330. "builtins::float::conv::__fixsfsi(a)");
  331. gen(|a: MyF32| i128(a.0).ok(),
  332. "builtins::float::conv::__fixsfti(a)");
  333. gen(|a: MyF64| i128(a.0).ok(),
  334. "builtins::float::conv::__fixdfti(a)");
  335. gen(|a: MyF64| u64(a.0).ok(),
  336. "builtins::float::conv::__fixunsdfdi(a)");
  337. gen(|a: MyF64| u32(a.0).ok(),
  338. "builtins::float::conv::__fixunsdfsi(a)");
  339. gen(|a: MyF32| u64(a.0).ok(),
  340. "builtins::float::conv::__fixunssfdi(a)");
  341. gen(|a: MyF32| u32(a.0).ok(),
  342. "builtins::float::conv::__fixunssfsi(a)");
  343. gen(|a: MyF32| u128(a.0).ok(),
  344. "builtins::float::conv::__fixunssfti(a)");
  345. gen(|a: MyF64| u128(a.0).ok(),
  346. "builtins::float::conv::__fixunsdfti(a)");
  347. gen(|a: MyI64| Some(f64(a.0)),
  348. "builtins::float::conv::__floatdidf(a)");
  349. gen(|a: MyI32| Some(f64(a.0)),
  350. "builtins::float::conv::__floatsidf(a)");
  351. gen(|a: MyI32| Some(f32(a.0)),
  352. "builtins::float::conv::__floatsisf(a)");
  353. gen(|a: MyU64| Some(f64(a.0)),
  354. "builtins::float::conv::__floatundidf(a)");
  355. gen(|a: MyU32| Some(f64(a.0)),
  356. "builtins::float::conv::__floatunsidf(a)");
  357. gen(|a: MyU32| Some(f32(a.0)),
  358. "builtins::float::conv::__floatunsisf(a)");
  359. gen(|a: MyU128| f32(a.0).ok(),
  360. "builtins::float::conv::__floatuntisf(a)");
  361. if !target_arch_mips {
  362. gen(|a: MyI128| Some(f32(a.0)),
  363. "builtins::float::conv::__floattisf(a)");
  364. gen(|a: MyI128| Some(f64(a.0)),
  365. "builtins::float::conv::__floattidf(a)");
  366. gen(|a: MyU128| Some(f64(a.0)),
  367. "builtins::float::conv::__floatuntidf(a)");
  368. }
  369. // float/pow.rs
  370. gen(|(a, b): (MyF64, MyI32)| {
  371. let c = a.0.powi(b.0);
  372. if a.0.is_nan() || c.is_nan() {
  373. None
  374. } else {
  375. Some(c)
  376. }
  377. },
  378. "builtins::float::pow::__powidf2(a, b)");
  379. gen(|(a, b): (MyF32, MyI32)| {
  380. let c = a.0.powi(b.0);
  381. if a.0.is_nan() || c.is_nan() {
  382. None
  383. } else {
  384. Some(c)
  385. }
  386. },
  387. "builtins::float::pow::__powisf2(a, b)");
  388. // float/sub.rs
  389. gen(|(a, b): (MyF64, MyF64)| {
  390. let c = a.0 - b.0;
  391. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  392. None
  393. } else {
  394. Some(c)
  395. }
  396. },
  397. "builtins::float::sub::__subdf3(a, b)");
  398. gen(|(a, b): (MyF32, MyF32)| {
  399. let c = a.0 - b.0;
  400. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  401. None
  402. } else {
  403. Some(c)
  404. }
  405. },
  406. "builtins::float::sub::__subsf3(a, b)");
  407. if target_arch_arm {
  408. gen(|(a, b): (MyF64, MyF64)| {
  409. let c = a.0 - b.0;
  410. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  411. None
  412. } else {
  413. Some(c)
  414. }
  415. },
  416. "builtins::float::sub::__subdf3vfp(a, b)");
  417. gen(|(a, b): (LargeF32, LargeF32)| {
  418. let c = a.0 - b.0;
  419. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  420. None
  421. } else {
  422. Some(c)
  423. }
  424. },
  425. "builtins::float::sub::__subsf3vfp(a, b)");
  426. }
  427. // float/mul.rs
  428. gen(|(a, b): (MyF64, MyF64)| {
  429. let c = a.0 * b.0;
  430. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  431. None
  432. } else {
  433. Some(c)
  434. }
  435. },
  436. "builtins::float::mul::__muldf3(a, b)");
  437. gen(|(a, b): (LargeF32, LargeF32)| {
  438. let c = a.0 * b.0;
  439. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  440. None
  441. } else {
  442. Some(c)
  443. }
  444. },
  445. "builtins::float::mul::__mulsf3(a, b)");
  446. if target_arch_arm {
  447. gen(|(a, b): (MyF64, MyF64)| {
  448. let c = a.0 * b.0;
  449. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  450. None
  451. } else {
  452. Some(c)
  453. }
  454. },
  455. "builtins::float::mul::__muldf3vfp(a, b)");
  456. gen(|(a, b): (LargeF32, LargeF32)| {
  457. let c = a.0 * b.0;
  458. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  459. None
  460. } else {
  461. Some(c)
  462. }
  463. },
  464. "builtins::float::mul::__mulsf3vfp(a, b)");
  465. }
  466. // float/div.rs
  467. gen(|(a, b): (MyF64, MyF64)| {
  468. if b.0 == 0.0 {
  469. return None
  470. }
  471. let c = a.0 / b.0;
  472. if a.0.is_nan() || b.0.is_nan() || c.is_nan() ||
  473. c.abs() <= unsafe { mem::transmute(4503599627370495u64) }
  474. {
  475. None
  476. } else {
  477. Some(c)
  478. }
  479. },
  480. "builtins::float::div::__divdf3(a, b)");
  481. gen(|(a, b): (LargeF32, LargeF32)| {
  482. if b.0 == 0.0 {
  483. return None
  484. }
  485. let c = a.0 / b.0;
  486. if a.0.is_nan() || b.0.is_nan() || c.is_nan() ||
  487. c.abs() <= unsafe { mem::transmute(16777215u32) }
  488. {
  489. None
  490. } else {
  491. Some(c)
  492. }
  493. },
  494. "builtins::float::div::__divsf3(a, b)");
  495. if target_arch_arm {
  496. gen(|(a, b): (MyF64, MyF64)| {
  497. if b.0 == 0.0 {
  498. return None
  499. }
  500. let c = a.0 / b.0;
  501. if a.0.is_nan() || b.0.is_nan() || c.is_nan() ||
  502. c.abs() <= unsafe { mem::transmute(4503599627370495u64) }
  503. {
  504. None
  505. } else {
  506. Some(c)
  507. }
  508. },
  509. "builtins::float::div::__divdf3vfp(a, b)");
  510. gen(|(a, b): (LargeF32, LargeF32)| {
  511. if b.0 == 0.0 {
  512. return None
  513. }
  514. let c = a.0 / b.0;
  515. if a.0.is_nan() || b.0.is_nan() || c.is_nan() ||
  516. c.abs() <= unsafe { mem::transmute(16777215u32) }
  517. {
  518. None
  519. } else {
  520. Some(c)
  521. }
  522. },
  523. "builtins::float::div::__divsf3vfp(a, b)");
  524. }
  525. // int/addsub.rs
  526. gen(|(a, b): (MyU128, MyU128)| Some(a.0.wrapping_add(b.0)),
  527. "builtins::int::addsub::rust_u128_add(a, b)");
  528. gen(|(a, b): (MyI128, MyI128)| Some(a.0.wrapping_add(b.0)),
  529. "builtins::int::addsub::rust_i128_add(a, b)");
  530. gen(|(a, b): (MyU128, MyU128)| Some(a.0.overflowing_add(b.0)),
  531. "builtins::int::addsub::rust_u128_addo(a, b)");
  532. gen(|(a, b): (MyI128, MyI128)| Some(a.0.overflowing_add(b.0)),
  533. "builtins::int::addsub::rust_i128_addo(a, b)");
  534. gen(|(a, b): (MyU128, MyU128)| Some(a.0.wrapping_sub(b.0)),
  535. "builtins::int::addsub::rust_u128_sub(a, b)");
  536. gen(|(a, b): (MyI128, MyI128)| Some(a.0.wrapping_sub(b.0)),
  537. "builtins::int::addsub::rust_i128_sub(a, b)");
  538. gen(|(a, b): (MyU128, MyU128)| Some(a.0.overflowing_sub(b.0)),
  539. "builtins::int::addsub::rust_u128_subo(a, b)");
  540. gen(|(a, b): (MyI128, MyI128)| Some(a.0.overflowing_sub(b.0)),
  541. "builtins::int::addsub::rust_i128_subo(a, b)");
  542. // int/mul.rs
  543. gen(|(a, b): (MyU64, MyU64)| Some(a.0.wrapping_mul(b.0)),
  544. "builtins::int::mul::__muldi3(a, b)");
  545. gen(|(a, b): (MyI64, MyI64)| Some(a.0.overflowing_mul(b.0)),
  546. "{
  547. let mut o = 2;
  548. let c = builtins::int::mul::__mulodi4(a, b, &mut o);
  549. (c, match o { 0 => false, 1 => true, _ => panic!() })
  550. }");
  551. gen(|(a, b): (MyI32, MyI32)| Some(a.0.overflowing_mul(b.0)),
  552. "{
  553. let mut o = 2;
  554. let c = builtins::int::mul::__mulosi4(a, b, &mut o);
  555. (c, match o { 0 => false, 1 => true, _ => panic!() })
  556. }");
  557. gen(|(a, b): (MyI128, MyI128)| Some(a.0.wrapping_mul(b.0)),
  558. "builtins::int::mul::__multi3(a, b)");
  559. gen(|(a, b): (MyI128, MyI128)| Some(a.0.overflowing_mul(b.0)),
  560. "{
  561. let mut o = 2;
  562. let c = builtins::int::mul::__muloti4(a, b, &mut o);
  563. (c, match o { 0 => false, 1 => true, _ => panic!() })
  564. }");
  565. // int/sdiv.rs
  566. gen(|(a, b): (MyI64, MyI64)| {
  567. if b.0 == 0 {
  568. None
  569. } else {
  570. Some(a.0 / b.0)
  571. }
  572. },
  573. "builtins::int::sdiv::__divdi3(a, b)");
  574. gen(|(a, b): (MyI64, MyI64)| {
  575. if b.0 == 0 {
  576. None
  577. } else {
  578. Some((a.0 / b.0, a.0 % b.0))
  579. }
  580. },
  581. "{
  582. let mut r = 0;
  583. (builtins::int::sdiv::__divmoddi4(a, b, &mut r), r)
  584. }");
  585. gen(|(a, b): (MyI32, MyI32)| {
  586. if b.0 == 0 {
  587. None
  588. } else {
  589. Some((a.0 / b.0, a.0 % b.0))
  590. }
  591. },
  592. "{
  593. let mut r = 0;
  594. (builtins::int::sdiv::__divmodsi4(a, b, &mut r), r)
  595. }");
  596. gen(|(a, b): (MyI32, MyI32)| {
  597. if b.0 == 0 {
  598. None
  599. } else {
  600. Some(a.0 / b.0)
  601. }
  602. },
  603. "builtins::int::sdiv::__divsi3(a, b)");
  604. gen(|(a, b): (MyI32, MyI32)| {
  605. if b.0 == 0 {
  606. None
  607. } else {
  608. Some(a.0 % b.0)
  609. }
  610. },
  611. "builtins::int::sdiv::__modsi3(a, b)");
  612. gen(|(a, b): (MyI64, MyI64)| {
  613. if b.0 == 0 {
  614. None
  615. } else {
  616. Some(a.0 % b.0)
  617. }
  618. },
  619. "builtins::int::sdiv::__moddi3(a, b)");
  620. gen(|(a, b): (MyI128, MyI128)| {
  621. if b.0 == 0 {
  622. None
  623. } else {
  624. Some(a.0 / b.0)
  625. }
  626. },
  627. "builtins::int::sdiv::__divti3(a, b)");
  628. gen(|(a, b): (MyI128, MyI128)| {
  629. if b.0 == 0 {
  630. None
  631. } else {
  632. Some(a.0 % b.0)
  633. }
  634. },
  635. "builtins::int::sdiv::__modti3(a, b)");
  636. // int/shift.rs
  637. gen(|(a, b): (MyU64, MyU32)| Some(a.0 << (b.0 % 64)),
  638. "builtins::int::shift::__ashldi3(a, b % 64)");
  639. gen(|(a, b): (MyU128, MyU32)| Some(a.0 << (b.0 % 128)),
  640. "builtins::int::shift::__ashlti3(a, b % 128)");
  641. gen(|(a, b): (MyI64, MyU32)| Some(a.0 >> (b.0 % 64)),
  642. "builtins::int::shift::__ashrdi3(a, b % 64)");
  643. gen(|(a, b): (MyI128, MyU32)| Some(a.0 >> (b.0 % 128)),
  644. "builtins::int::shift::__ashrti3(a, b % 128)");
  645. gen(|(a, b): (MyU64, MyU32)| Some(a.0 >> (b.0 % 64)),
  646. "builtins::int::shift::__lshrdi3(a, b % 64)");
  647. gen(|(a, b): (MyU128, MyU32)| Some(a.0 >> (b.0 % 128)),
  648. "builtins::int::shift::__lshrti3(a, b % 128)");
  649. // int/udiv.rs
  650. gen(|(a, b): (MyU64, MyU64)| {
  651. if b.0 == 0 {
  652. None
  653. } else {
  654. Some(a.0 / b.0)
  655. }
  656. },
  657. "builtins::int::udiv::__udivdi3(a, b)");
  658. gen(|(a, b): (MyU64, MyU64)| {
  659. if b.0 == 0 {
  660. None
  661. } else {
  662. Some((a.0 / b.0, a.0 % b.0))
  663. }
  664. },
  665. "{
  666. let mut r = 0;
  667. (builtins::int::udiv::__udivmoddi4(a, b, Some(&mut r)), r)
  668. }");
  669. gen(|(a, b): (MyU32, MyU32)| {
  670. if b.0 == 0 {
  671. None
  672. } else {
  673. Some((a.0 / b.0, a.0 % b.0))
  674. }
  675. },
  676. "{
  677. let mut r = 0;
  678. (builtins::int::udiv::__udivmodsi4(a, b, Some(&mut r)), r)
  679. }");
  680. gen(|(a, b): (MyU32, MyU32)| {
  681. if b.0 == 0 {
  682. None
  683. } else {
  684. Some(a.0 / b.0)
  685. }
  686. },
  687. "builtins::int::udiv::__udivsi3(a, b)");
  688. gen(|(a, b): (MyU32, MyU32)| {
  689. if b.0 == 0 {
  690. None
  691. } else {
  692. Some(a.0 % b.0)
  693. }
  694. },
  695. "builtins::int::udiv::__umodsi3(a, b)");
  696. gen(|(a, b): (MyU64, MyU64)| {
  697. if b.0 == 0 {
  698. None
  699. } else {
  700. Some(a.0 % b.0)
  701. }
  702. },
  703. "builtins::int::udiv::__umoddi3(a, b)");
  704. gen(|(a, b): (MyU128, MyU128)| {
  705. if b.0 == 0 {
  706. None
  707. } else {
  708. Some(a.0 / b.0)
  709. }
  710. },
  711. "builtins::int::udiv::__udivti3(a, b)");
  712. gen(|(a, b): (MyU128, MyU128)| {
  713. if b.0 == 0 {
  714. None
  715. } else {
  716. Some(a.0 % b.0)
  717. }
  718. },
  719. "builtins::int::udiv::__umodti3(a, b)");
  720. gen(|(a, b): (MyU128, MyU128)| {
  721. if b.0 == 0 {
  722. None
  723. } else {
  724. Some((a.0 / b.0, a.0 % b.0))
  725. }
  726. },
  727. "{
  728. let mut r = 0;
  729. (builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r)
  730. }");
  731. }
  732. macro_rules! gen_float {
  733. ($name:ident,
  734. $fty:ident,
  735. $uty:ident,
  736. $bits:expr,
  737. $significand_bits:expr) => {
  738. pub fn $name<R>(rng: &mut R) -> $fty
  739. where
  740. R: Rng,
  741. {
  742. const BITS: u8 = $bits;
  743. const SIGNIFICAND_BITS: u8 = $significand_bits;
  744. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  745. const SIGN_MASK: $uty = (1 << (BITS - 1));
  746. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  747. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  748. unsafe {
  749. mem::transmute(((sign as $uty) << (BITS - 1)) |
  750. ((exponent & EXPONENT_MASK) <<
  751. SIGNIFICAND_BITS) |
  752. (significand & SIGNIFICAND_MASK))
  753. }
  754. }
  755. if rng.gen_weighted_bool(10) {
  756. // Special values
  757. *rng.choose(&[-0.0,
  758. 0.0,
  759. ::std::$fty::MIN,
  760. ::std::$fty::MIN_POSITIVE,
  761. ::std::$fty::MAX,
  762. ::std::$fty::NAN,
  763. ::std::$fty::INFINITY,
  764. -::std::$fty::INFINITY])
  765. .unwrap()
  766. } else if rng.gen_weighted_bool(10) {
  767. // NaN patterns
  768. mk_f32(rng.gen(), rng.gen(), 0)
  769. } else if rng.gen() {
  770. // Denormalized
  771. mk_f32(rng.gen(), 0, rng.gen())
  772. } else {
  773. // Random anything
  774. mk_f32(rng.gen(), rng.gen(), rng.gen())
  775. }
  776. }
  777. }
  778. }
  779. gen_float!(gen_f32, f32, u32, 32, 23);
  780. gen_float!(gen_f64, f64, u64, 64, 52);
  781. macro_rules! gen_large_float {
  782. ($name:ident,
  783. $fty:ident,
  784. $uty:ident,
  785. $bits:expr,
  786. $significand_bits:expr) => {
  787. pub fn $name<R>(rng: &mut R) -> $fty
  788. where
  789. R: Rng,
  790. {
  791. const BITS: u8 = $bits;
  792. const SIGNIFICAND_BITS: u8 = $significand_bits;
  793. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  794. const SIGN_MASK: $uty = (1 << (BITS - 1));
  795. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  796. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  797. unsafe {
  798. mem::transmute(((sign as $uty) << (BITS - 1)) |
  799. ((exponent & EXPONENT_MASK) <<
  800. SIGNIFICAND_BITS) |
  801. (significand & SIGNIFICAND_MASK))
  802. }
  803. }
  804. if rng.gen_weighted_bool(10) {
  805. // Special values
  806. *rng.choose(&[-0.0,
  807. 0.0,
  808. ::std::$fty::MIN,
  809. ::std::$fty::MIN_POSITIVE,
  810. ::std::$fty::MAX,
  811. ::std::$fty::NAN,
  812. ::std::$fty::INFINITY,
  813. -::std::$fty::INFINITY])
  814. .unwrap()
  815. } else if rng.gen_weighted_bool(10) {
  816. // NaN patterns
  817. mk_f32(rng.gen(), rng.gen(), 0)
  818. } else if rng.gen() {
  819. // Denormalized
  820. mk_f32(rng.gen(), 0, rng.gen())
  821. } else {
  822. // Random anything
  823. rng.gen::<$fty>()
  824. }
  825. }
  826. }
  827. }
  828. gen_large_float!(gen_large_f32, f32, u32, 32, 23);
  829. gen_large_float!(gen_large_f64, f64, u64, 64, 52);
  830. trait TestInput: rand::Rand + Hash + Eq + fmt::Debug {
  831. fn ty_name() -> String;
  832. fn generate_lets(container: &str, cnt: &mut u8) -> String;
  833. fn generate_static(&self, dst: &mut String);
  834. }
  835. trait TestOutput {
  836. fn ty_name() -> String;
  837. fn generate_static(&self, dst: &mut String);
  838. fn generate_expr(container: &str) -> String;
  839. }
  840. fn gen<F, A, R>(mut generate: F, test: &str)
  841. where F: FnMut(A) -> Option<R>,
  842. A: TestInput + Copy,
  843. R: TestOutput,
  844. {
  845. let rng = &mut rand::thread_rng();
  846. let testname = test.split("::")
  847. .last()
  848. .unwrap()
  849. .split("(")
  850. .next()
  851. .unwrap();
  852. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  853. let out_file = out_dir.join("generated.rs");
  854. let mut testcases = HashMap::new();
  855. let mut n = NTESTS;
  856. while n > 0 {
  857. let input: A = rng.gen();
  858. if testcases.contains_key(&input) {
  859. continue
  860. }
  861. let output = match generate(input) {
  862. Some(o) => o,
  863. None => continue,
  864. };
  865. testcases.insert(input, output);
  866. n -= 1;
  867. }
  868. let mut contents = String::new();
  869. contents.push_str(&format!("mod {} {{\nuse super::*;\n", testname));
  870. contents.push_str("#[test]\n");
  871. contents.push_str("fn test() {\n");
  872. contents.push_str(&format!("static TESTS: [({}, {}); {}] = [\n",
  873. A::ty_name(),
  874. R::ty_name(),
  875. NTESTS));
  876. for (input, output) in testcases {
  877. contents.push_str(" (");
  878. input.generate_static(&mut contents);
  879. contents.push_str(", ");
  880. output.generate_static(&mut contents);
  881. contents.push_str("),\n");
  882. }
  883. contents.push_str("];\n");
  884. contents.push_str(&format!(r#"
  885. for &(inputs, output) in TESTS.iter() {{
  886. {}
  887. assert_eq!({}, {}, "inputs {{:?}}", inputs)
  888. }}
  889. "#,
  890. A::generate_lets("inputs", &mut 0),
  891. R::generate_expr("output"),
  892. test,
  893. ));
  894. contents.push_str("\n}\n");
  895. contents.push_str("\n}\n");
  896. OpenOptions::new()
  897. .write(true)
  898. .append(true)
  899. .create(true)
  900. .open(out_file)
  901. .unwrap()
  902. .write_all(contents.as_bytes())
  903. .unwrap();
  904. }
  905. macro_rules! my_float {
  906. ($(struct $name:ident($inner:ident) = $gen:ident;)*) => ($(
  907. #[derive(Debug, Clone, Copy)]
  908. struct $name($inner);
  909. impl TestInput for $name {
  910. fn ty_name() -> String {
  911. format!("u{}", &stringify!($inner)[1..])
  912. }
  913. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  914. let me = *cnt;
  915. *cnt += 1;
  916. format!("let {} = {}::from_bits({});\n",
  917. (b'a' + me) as char,
  918. stringify!($inner),
  919. container)
  920. }
  921. fn generate_static(&self, dst: &mut String) {
  922. write!(dst, "{}", self.0.to_bits()).unwrap();
  923. }
  924. }
  925. impl rand::Rand for $name {
  926. fn rand<R: rand::Rng>(r: &mut R) -> $name {
  927. $name($gen(r))
  928. }
  929. }
  930. impl Hash for $name {
  931. fn hash<H: Hasher>(&self, h: &mut H) {
  932. self.0.to_bits().hash(h)
  933. }
  934. }
  935. impl PartialEq for $name {
  936. fn eq(&self, other: &$name) -> bool {
  937. self.0.to_bits() == other.0.to_bits()
  938. }
  939. }
  940. impl Eq for $name {}
  941. )*)
  942. }
  943. my_float! {
  944. struct MyF64(f64) = gen_f64;
  945. struct LargeF64(f64) = gen_large_f64;
  946. struct MyF32(f32) = gen_f32;
  947. struct LargeF32(f32) = gen_large_f32;
  948. }
  949. macro_rules! my_integer {
  950. ($(struct $name:ident($inner:ident);)*) => ($(
  951. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
  952. struct $name($inner);
  953. impl TestInput for $name {
  954. fn ty_name() -> String {
  955. stringify!($inner).to_string()
  956. }
  957. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  958. let me = *cnt;
  959. *cnt += 1;
  960. format!("let {} = {};\n",
  961. (b'a' + me) as char,
  962. container)
  963. }
  964. fn generate_static(&self, dst: &mut String) {
  965. write!(dst, "{}", self.0).unwrap();
  966. }
  967. }
  968. impl rand::Rand for $name {
  969. fn rand<R: rand::Rng>(rng: &mut R) -> $name {
  970. let bits = (0 as $inner).count_zeros();
  971. let mut mk = || {
  972. if rng.gen_weighted_bool(10) {
  973. *rng.choose(&[
  974. ::std::$inner::MAX >> (bits / 2),
  975. 0,
  976. ::std::$inner::MIN >> (bits / 2),
  977. ]).unwrap()
  978. } else {
  979. rng.gen::<$inner>()
  980. }
  981. };
  982. let a = mk();
  983. let b = mk();
  984. $name((a << (bits / 2)) | (b & (!0 << (bits / 2))))
  985. }
  986. }
  987. )*)
  988. }
  989. my_integer! {
  990. struct MyI32(i32);
  991. struct MyI64(i64);
  992. struct MyI128(i128);
  993. struct MyU32(u32);
  994. struct MyU64(u64);
  995. struct MyU128(u128);
  996. }
  997. impl<A, B> TestInput for (A, B)
  998. where A: TestInput,
  999. B: TestInput,
  1000. {
  1001. fn ty_name() -> String {
  1002. format!("({}, {})", A::ty_name(), B::ty_name())
  1003. }
  1004. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1005. format!("{}{}",
  1006. A::generate_lets(&format!("{}.0", container), cnt),
  1007. B::generate_lets(&format!("{}.1", container), cnt))
  1008. }
  1009. fn generate_static(&self, dst: &mut String) {
  1010. dst.push_str("(");
  1011. self.0.generate_static(dst);
  1012. dst.push_str(", ");
  1013. self.1.generate_static(dst);
  1014. dst.push_str(")");
  1015. }
  1016. }
  1017. impl TestOutput for f64 {
  1018. fn ty_name() -> String {
  1019. "u64".to_string()
  1020. }
  1021. fn generate_static(&self, dst: &mut String) {
  1022. write!(dst, "{}", self.to_bits()).unwrap();
  1023. }
  1024. fn generate_expr(container: &str) -> String {
  1025. format!("f64::from_bits({})", container)
  1026. }
  1027. }
  1028. impl TestOutput for f32 {
  1029. fn ty_name() -> String {
  1030. "u32".to_string()
  1031. }
  1032. fn generate_static(&self, dst: &mut String) {
  1033. write!(dst, "{}", self.to_bits()).unwrap();
  1034. }
  1035. fn generate_expr(container: &str) -> String {
  1036. format!("f32::from_bits({})", container)
  1037. }
  1038. }
  1039. macro_rules! plain_test_output {
  1040. ($($i:tt)*) => ($(
  1041. impl TestOutput for $i {
  1042. fn ty_name() -> String {
  1043. stringify!($i).to_string()
  1044. }
  1045. fn generate_static(&self, dst: &mut String) {
  1046. write!(dst, "{}", self).unwrap();
  1047. }
  1048. fn generate_expr(container: &str) -> String {
  1049. container.to_string()
  1050. }
  1051. }
  1052. )*)
  1053. }
  1054. plain_test_output!(i32 i64 i128 u32 u64 u128 bool);
  1055. impl<A, B> TestOutput for (A, B)
  1056. where A: TestOutput,
  1057. B: TestOutput,
  1058. {
  1059. fn ty_name() -> String {
  1060. format!("({}, {})", A::ty_name(), B::ty_name())
  1061. }
  1062. fn generate_static(&self, dst: &mut String) {
  1063. dst.push_str("(");
  1064. self.0.generate_static(dst);
  1065. dst.push_str(", ");
  1066. self.1.generate_static(dst);
  1067. dst.push_str(")");
  1068. }
  1069. fn generate_expr(container: &str) -> String {
  1070. container.to_string()
  1071. }
  1072. }