build.rs 36 KB

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