build.rs 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168
  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. if !target_arch_mips { // FIXME(#137)
  560. gen(|(a, b): (MyI128, MyI128)| Some(a.0.overflowing_mul(b.0)),
  561. "{
  562. let mut o = 2;
  563. let c = builtins::int::mul::__muloti4(a, b, &mut o);
  564. (c, match o { 0 => false, 1 => true, _ => panic!() })
  565. }");
  566. }
  567. // int/sdiv.rs
  568. gen(|(a, b): (MyI64, MyI64)| {
  569. if b.0 == 0 {
  570. None
  571. } else {
  572. Some(a.0 / b.0)
  573. }
  574. },
  575. "builtins::int::sdiv::__divdi3(a, b)");
  576. gen(|(a, b): (MyI64, MyI64)| {
  577. if b.0 == 0 {
  578. None
  579. } else {
  580. Some((a.0 / b.0, a.0 % b.0))
  581. }
  582. },
  583. "{
  584. let mut r = 0;
  585. (builtins::int::sdiv::__divmoddi4(a, b, &mut r), r)
  586. }");
  587. gen(|(a, b): (MyI32, MyI32)| {
  588. if b.0 == 0 {
  589. None
  590. } else {
  591. Some((a.0 / b.0, a.0 % b.0))
  592. }
  593. },
  594. "{
  595. let mut r = 0;
  596. (builtins::int::sdiv::__divmodsi4(a, b, &mut r), r)
  597. }");
  598. gen(|(a, b): (MyI32, MyI32)| {
  599. if b.0 == 0 {
  600. None
  601. } else {
  602. Some(a.0 / b.0)
  603. }
  604. },
  605. "builtins::int::sdiv::__divsi3(a, b)");
  606. gen(|(a, b): (MyI32, MyI32)| {
  607. if b.0 == 0 {
  608. None
  609. } else {
  610. Some(a.0 % b.0)
  611. }
  612. },
  613. "builtins::int::sdiv::__modsi3(a, b)");
  614. gen(|(a, b): (MyI64, MyI64)| {
  615. if b.0 == 0 {
  616. None
  617. } else {
  618. Some(a.0 % b.0)
  619. }
  620. },
  621. "builtins::int::sdiv::__moddi3(a, b)");
  622. if !target_arch_mips { // FIXME(#137)
  623. gen(|(a, b): (MyI128, MyI128)| {
  624. if b.0 == 0 {
  625. None
  626. } else {
  627. Some(a.0 / b.0)
  628. }
  629. },
  630. "builtins::int::sdiv::__divti3(a, b)");
  631. gen(|(a, b): (MyI128, MyI128)| {
  632. if b.0 == 0 {
  633. None
  634. } else {
  635. Some(a.0 % b.0)
  636. }
  637. },
  638. "builtins::int::sdiv::__modti3(a, b)");
  639. }
  640. // int/shift.rs
  641. gen(|(a, b): (MyU64, MyU32)| Some(a.0 << (b.0 % 64)),
  642. "builtins::int::shift::__ashldi3(a, b % 64)");
  643. gen(|(a, b): (MyU128, MyU32)| Some(a.0 << (b.0 % 128)),
  644. "builtins::int::shift::__ashlti3(a, b % 128)");
  645. gen(|(a, b): (MyI64, MyU32)| Some(a.0 >> (b.0 % 64)),
  646. "builtins::int::shift::__ashrdi3(a, b % 64)");
  647. gen(|(a, b): (MyI128, MyU32)| Some(a.0 >> (b.0 % 128)),
  648. "builtins::int::shift::__ashrti3(a, b % 128)");
  649. gen(|(a, b): (MyU64, MyU32)| Some(a.0 >> (b.0 % 64)),
  650. "builtins::int::shift::__lshrdi3(a, b % 64)");
  651. gen(|(a, b): (MyU128, MyU32)| Some(a.0 >> (b.0 % 128)),
  652. "builtins::int::shift::__lshrti3(a, b % 128)");
  653. // int/udiv.rs
  654. gen(|(a, b): (MyU64, MyU64)| {
  655. if b.0 == 0 {
  656. None
  657. } else {
  658. Some(a.0 / b.0)
  659. }
  660. },
  661. "builtins::int::udiv::__udivdi3(a, b)");
  662. gen(|(a, b): (MyU64, MyU64)| {
  663. if b.0 == 0 {
  664. None
  665. } else {
  666. Some((a.0 / b.0, a.0 % b.0))
  667. }
  668. },
  669. "{
  670. let mut r = 0;
  671. (builtins::int::udiv::__udivmoddi4(a, b, Some(&mut r)), r)
  672. }");
  673. gen(|(a, b): (MyU32, MyU32)| {
  674. if b.0 == 0 {
  675. None
  676. } else {
  677. Some((a.0 / b.0, a.0 % b.0))
  678. }
  679. },
  680. "{
  681. let mut r = 0;
  682. (builtins::int::udiv::__udivmodsi4(a, b, Some(&mut r)), r)
  683. }");
  684. gen(|(a, b): (MyU32, MyU32)| {
  685. if b.0 == 0 {
  686. None
  687. } else {
  688. Some(a.0 / b.0)
  689. }
  690. },
  691. "builtins::int::udiv::__udivsi3(a, b)");
  692. gen(|(a, b): (MyU32, MyU32)| {
  693. if b.0 == 0 {
  694. None
  695. } else {
  696. Some(a.0 % b.0)
  697. }
  698. },
  699. "builtins::int::udiv::__umodsi3(a, b)");
  700. gen(|(a, b): (MyU64, MyU64)| {
  701. if b.0 == 0 {
  702. None
  703. } else {
  704. Some(a.0 % b.0)
  705. }
  706. },
  707. "builtins::int::udiv::__umoddi3(a, b)");
  708. if !target_arch_mips { // FIXME(#137)
  709. gen(|(a, b): (MyU128, MyU128)| {
  710. if b.0 == 0 {
  711. None
  712. } else {
  713. Some(a.0 / b.0)
  714. }
  715. },
  716. "builtins::int::udiv::__udivti3(a, b)");
  717. gen(|(a, b): (MyU128, MyU128)| {
  718. if b.0 == 0 {
  719. None
  720. } else {
  721. Some(a.0 % b.0)
  722. }
  723. },
  724. "builtins::int::udiv::__umodti3(a, b)");
  725. gen(|(a, b): (MyU128, MyU128)| {
  726. if b.0 == 0 {
  727. None
  728. } else {
  729. Some((a.0 / b.0, a.0 % b.0))
  730. }
  731. },
  732. "{
  733. let mut r = 0;
  734. (builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r)
  735. }");
  736. }
  737. }
  738. macro_rules! gen_float {
  739. ($name:ident,
  740. $fty:ident,
  741. $uty:ident,
  742. $bits:expr,
  743. $significand_bits:expr) => {
  744. pub fn $name<R>(rng: &mut R) -> $fty
  745. where
  746. R: Rng,
  747. {
  748. const BITS: u8 = $bits;
  749. const SIGNIFICAND_BITS: u8 = $significand_bits;
  750. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  751. const SIGN_MASK: $uty = (1 << (BITS - 1));
  752. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  753. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  754. unsafe {
  755. mem::transmute(((sign as $uty) << (BITS - 1)) |
  756. ((exponent & EXPONENT_MASK) <<
  757. SIGNIFICAND_BITS) |
  758. (significand & SIGNIFICAND_MASK))
  759. }
  760. }
  761. if rng.gen_weighted_bool(10) {
  762. // Special values
  763. *rng.choose(&[-0.0,
  764. 0.0,
  765. ::std::$fty::MIN,
  766. ::std::$fty::MIN_POSITIVE,
  767. ::std::$fty::MAX,
  768. ::std::$fty::NAN,
  769. ::std::$fty::INFINITY,
  770. -::std::$fty::INFINITY])
  771. .unwrap()
  772. } else if rng.gen_weighted_bool(10) {
  773. // NaN patterns
  774. mk_f32(rng.gen(), rng.gen(), 0)
  775. } else if rng.gen() {
  776. // Denormalized
  777. mk_f32(rng.gen(), 0, rng.gen())
  778. } else {
  779. // Random anything
  780. mk_f32(rng.gen(), rng.gen(), rng.gen())
  781. }
  782. }
  783. }
  784. }
  785. gen_float!(gen_f32, f32, u32, 32, 23);
  786. gen_float!(gen_f64, f64, u64, 64, 52);
  787. macro_rules! gen_large_float {
  788. ($name:ident,
  789. $fty:ident,
  790. $uty:ident,
  791. $bits:expr,
  792. $significand_bits:expr) => {
  793. pub fn $name<R>(rng: &mut R) -> $fty
  794. where
  795. R: Rng,
  796. {
  797. const BITS: u8 = $bits;
  798. const SIGNIFICAND_BITS: u8 = $significand_bits;
  799. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  800. const SIGN_MASK: $uty = (1 << (BITS - 1));
  801. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  802. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  803. unsafe {
  804. mem::transmute(((sign as $uty) << (BITS - 1)) |
  805. ((exponent & EXPONENT_MASK) <<
  806. SIGNIFICAND_BITS) |
  807. (significand & SIGNIFICAND_MASK))
  808. }
  809. }
  810. if rng.gen_weighted_bool(10) {
  811. // Special values
  812. *rng.choose(&[-0.0,
  813. 0.0,
  814. ::std::$fty::MIN,
  815. ::std::$fty::MIN_POSITIVE,
  816. ::std::$fty::MAX,
  817. ::std::$fty::NAN,
  818. ::std::$fty::INFINITY,
  819. -::std::$fty::INFINITY])
  820. .unwrap()
  821. } else if rng.gen_weighted_bool(10) {
  822. // NaN patterns
  823. mk_f32(rng.gen(), rng.gen(), 0)
  824. } else if rng.gen() {
  825. // Denormalized
  826. mk_f32(rng.gen(), 0, rng.gen())
  827. } else {
  828. // Random anything
  829. rng.gen::<$fty>()
  830. }
  831. }
  832. }
  833. }
  834. gen_large_float!(gen_large_f32, f32, u32, 32, 23);
  835. gen_large_float!(gen_large_f64, f64, u64, 64, 52);
  836. trait TestInput: rand::Rand + Hash + Eq + fmt::Debug {
  837. fn ty_name() -> String;
  838. fn generate_lets(container: &str, cnt: &mut u8) -> String;
  839. fn generate_static(&self, dst: &mut String);
  840. }
  841. trait TestOutput {
  842. fn ty_name() -> String;
  843. fn generate_static(&self, dst: &mut String);
  844. fn generate_expr(container: &str) -> String;
  845. }
  846. fn gen<F, A, R>(mut generate: F, test: &str)
  847. where F: FnMut(A) -> Option<R>,
  848. A: TestInput + Copy,
  849. R: TestOutput,
  850. {
  851. let rng = &mut rand::thread_rng();
  852. let testname = test.split("::")
  853. .last()
  854. .unwrap()
  855. .split("(")
  856. .next()
  857. .unwrap();
  858. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  859. let out_file = out_dir.join("generated.rs");
  860. let mut testcases = HashMap::new();
  861. let mut n = NTESTS;
  862. while n > 0 {
  863. let input: A = rng.gen();
  864. if testcases.contains_key(&input) {
  865. continue
  866. }
  867. let output = match generate(input) {
  868. Some(o) => o,
  869. None => continue,
  870. };
  871. testcases.insert(input, output);
  872. n -= 1;
  873. }
  874. let mut contents = String::new();
  875. contents.push_str(&format!("mod {} {{\nuse super::*;\n", testname));
  876. contents.push_str("#[test]\n");
  877. contents.push_str("fn test() {\n");
  878. contents.push_str(&format!("static TESTS: [({}, {}); {}] = [\n",
  879. A::ty_name(),
  880. R::ty_name(),
  881. NTESTS));
  882. for (input, output) in testcases {
  883. contents.push_str(" (");
  884. input.generate_static(&mut contents);
  885. contents.push_str(", ");
  886. output.generate_static(&mut contents);
  887. contents.push_str("),\n");
  888. }
  889. contents.push_str("];\n");
  890. contents.push_str(&format!(r#"
  891. for &(inputs, output) in TESTS.iter() {{
  892. {}
  893. assert_eq!({}, {}, "inputs {{:?}}", inputs)
  894. }}
  895. "#,
  896. A::generate_lets("inputs", &mut 0),
  897. R::generate_expr("output"),
  898. test,
  899. ));
  900. contents.push_str("\n}\n");
  901. contents.push_str("\n}\n");
  902. OpenOptions::new()
  903. .write(true)
  904. .append(true)
  905. .create(true)
  906. .open(out_file)
  907. .unwrap()
  908. .write_all(contents.as_bytes())
  909. .unwrap();
  910. }
  911. macro_rules! my_float {
  912. ($(struct $name:ident($inner:ident) = $gen:ident;)*) => ($(
  913. #[derive(Debug, Clone, Copy)]
  914. struct $name($inner);
  915. impl TestInput for $name {
  916. fn ty_name() -> String {
  917. format!("u{}", &stringify!($inner)[1..])
  918. }
  919. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  920. let me = *cnt;
  921. *cnt += 1;
  922. format!("let {} = {}::from_bits({});\n",
  923. (b'a' + me) as char,
  924. stringify!($inner),
  925. container)
  926. }
  927. fn generate_static(&self, dst: &mut String) {
  928. write!(dst, "{}", self.0.to_bits()).unwrap();
  929. }
  930. }
  931. impl rand::Rand for $name {
  932. fn rand<R: rand::Rng>(r: &mut R) -> $name {
  933. $name($gen(r))
  934. }
  935. }
  936. impl Hash for $name {
  937. fn hash<H: Hasher>(&self, h: &mut H) {
  938. self.0.to_bits().hash(h)
  939. }
  940. }
  941. impl PartialEq for $name {
  942. fn eq(&self, other: &$name) -> bool {
  943. self.0.to_bits() == other.0.to_bits()
  944. }
  945. }
  946. impl Eq for $name {}
  947. )*)
  948. }
  949. my_float! {
  950. struct MyF64(f64) = gen_f64;
  951. struct LargeF64(f64) = gen_large_f64;
  952. struct MyF32(f32) = gen_f32;
  953. struct LargeF32(f32) = gen_large_f32;
  954. }
  955. macro_rules! my_integer {
  956. ($(struct $name:ident($inner:ident);)*) => ($(
  957. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
  958. struct $name($inner);
  959. impl TestInput for $name {
  960. fn ty_name() -> String {
  961. stringify!($inner).to_string()
  962. }
  963. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  964. let me = *cnt;
  965. *cnt += 1;
  966. format!("let {} = {};\n",
  967. (b'a' + me) as char,
  968. container)
  969. }
  970. fn generate_static(&self, dst: &mut String) {
  971. write!(dst, "{}", self.0).unwrap();
  972. }
  973. }
  974. impl rand::Rand for $name {
  975. fn rand<R: rand::Rng>(rng: &mut R) -> $name {
  976. let bits = (0 as $inner).count_zeros();
  977. let mut mk = || {
  978. if rng.gen_weighted_bool(10) {
  979. *rng.choose(&[
  980. ::std::$inner::MAX >> (bits / 2),
  981. 0,
  982. ::std::$inner::MIN >> (bits / 2),
  983. ]).unwrap()
  984. } else {
  985. rng.gen::<$inner>()
  986. }
  987. };
  988. let a = mk();
  989. let b = mk();
  990. $name((a << (bits / 2)) | (b & (!0 << (bits / 2))))
  991. }
  992. }
  993. )*)
  994. }
  995. my_integer! {
  996. struct MyI32(i32);
  997. struct MyI64(i64);
  998. struct MyI128(i128);
  999. struct MyU32(u32);
  1000. struct MyU64(u64);
  1001. struct MyU128(u128);
  1002. }
  1003. impl<A, B> TestInput for (A, B)
  1004. where A: TestInput,
  1005. B: TestInput,
  1006. {
  1007. fn ty_name() -> String {
  1008. format!("({}, {})", A::ty_name(), B::ty_name())
  1009. }
  1010. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1011. format!("{}{}",
  1012. A::generate_lets(&format!("{}.0", container), cnt),
  1013. B::generate_lets(&format!("{}.1", container), cnt))
  1014. }
  1015. fn generate_static(&self, dst: &mut String) {
  1016. dst.push_str("(");
  1017. self.0.generate_static(dst);
  1018. dst.push_str(", ");
  1019. self.1.generate_static(dst);
  1020. dst.push_str(")");
  1021. }
  1022. }
  1023. impl TestOutput for f64 {
  1024. fn ty_name() -> String {
  1025. "u64".to_string()
  1026. }
  1027. fn generate_static(&self, dst: &mut String) {
  1028. write!(dst, "{}", self.to_bits()).unwrap();
  1029. }
  1030. fn generate_expr(container: &str) -> String {
  1031. format!("f64::from_bits({})", container)
  1032. }
  1033. }
  1034. impl TestOutput for f32 {
  1035. fn ty_name() -> String {
  1036. "u32".to_string()
  1037. }
  1038. fn generate_static(&self, dst: &mut String) {
  1039. write!(dst, "{}", self.to_bits()).unwrap();
  1040. }
  1041. fn generate_expr(container: &str) -> String {
  1042. format!("f32::from_bits({})", container)
  1043. }
  1044. }
  1045. macro_rules! plain_test_output {
  1046. ($($i:tt)*) => ($(
  1047. impl TestOutput for $i {
  1048. fn ty_name() -> String {
  1049. stringify!($i).to_string()
  1050. }
  1051. fn generate_static(&self, dst: &mut String) {
  1052. write!(dst, "{}", self).unwrap();
  1053. }
  1054. fn generate_expr(container: &str) -> String {
  1055. container.to_string()
  1056. }
  1057. }
  1058. )*)
  1059. }
  1060. plain_test_output!(i32 i64 i128 u32 u64 u128 bool);
  1061. impl<A, B> TestOutput for (A, B)
  1062. where A: TestOutput,
  1063. B: TestOutput,
  1064. {
  1065. fn ty_name() -> String {
  1066. format!("({}, {})", A::ty_name(), B::ty_name())
  1067. }
  1068. fn generate_static(&self, dst: &mut String) {
  1069. dst.push_str("(");
  1070. self.0.generate_static(dst);
  1071. dst.push_str(", ");
  1072. self.1.generate_static(dst);
  1073. dst.push_str(")");
  1074. }
  1075. fn generate_expr(container: &str) -> String {
  1076. container.to_string()
  1077. }
  1078. }