build.rs 27 KB

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