build.rs 30 KB

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