build.rs 35 KB

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