build.rs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. use rand::seq::SliceRandom;
  2. use rand::Rng;
  3. use std::collections::HashMap;
  4. use std::fmt;
  5. use std::fmt::Write as FmtWrite;
  6. use std::fs::{self, OpenOptions};
  7. use std::hash::{Hash, Hasher};
  8. use std::io::Write;
  9. use std::path::PathBuf;
  10. use std::{env, mem};
  11. const NTESTS: usize = 1_000;
  12. fn main() {
  13. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  14. let out_file = out_dir.join("generated.rs");
  15. drop(fs::remove_file(&out_file));
  16. let target = env::var("TARGET").unwrap();
  17. let target_arch_arm = target.contains("arm") || target.contains("thumb");
  18. let target_arch_mips = target.contains("mips");
  19. // TODO accept NaNs. We don't do that right now because we can't check
  20. // for NaN-ness on the thumb targets (due to missing intrinsics)
  21. // float/add.rs
  22. gen(
  23. |(a, b): (MyF64, MyF64)| {
  24. let c = a.0 + b.0;
  25. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  26. None
  27. } else {
  28. Some(c)
  29. }
  30. },
  31. "builtins::float::add::__adddf3(a, b)",
  32. );
  33. gen(
  34. |(a, b): (MyF32, MyF32)| {
  35. let c = a.0 + b.0;
  36. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  37. None
  38. } else {
  39. Some(c)
  40. }
  41. },
  42. "builtins::float::add::__addsf3(a, b)",
  43. );
  44. if target_arch_arm {
  45. gen(
  46. |(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. "builtins::float::add::__adddf3vfp(a, b)",
  55. );
  56. gen(
  57. |(a, b): (LargeF32, LargeF32)| {
  58. let c = a.0 + b.0;
  59. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  60. None
  61. } else {
  62. Some(c)
  63. }
  64. },
  65. "builtins::float::add::__addsf3vfp(a, b)",
  66. );
  67. }
  68. // float/cmp.rs
  69. gen(
  70. |(a, b): (MyF64, MyF64)| {
  71. let (a, b) = (a.0, b.0);
  72. if a.is_nan() || b.is_nan() {
  73. return None;
  74. }
  75. if a.is_nan() || b.is_nan() {
  76. Some(-1)
  77. } else if a < b {
  78. Some(-1)
  79. } else if a > b {
  80. Some(1)
  81. } else {
  82. Some(0)
  83. }
  84. },
  85. "builtins::float::cmp::__gedf2(a, b)",
  86. );
  87. gen(
  88. |(a, b): (MyF32, MyF32)| {
  89. let (a, b) = (a.0, b.0);
  90. if a.is_nan() || b.is_nan() {
  91. return None;
  92. }
  93. if a.is_nan() || b.is_nan() {
  94. Some(-1)
  95. } else if a < b {
  96. Some(-1)
  97. } else if a > b {
  98. Some(1)
  99. } else {
  100. Some(0)
  101. }
  102. },
  103. "builtins::float::cmp::__gesf2(a, b)",
  104. );
  105. gen(
  106. |(a, b): (MyF64, MyF64)| {
  107. let (a, b) = (a.0, b.0);
  108. if a.is_nan() || b.is_nan() {
  109. return None;
  110. }
  111. if a.is_nan() || b.is_nan() {
  112. Some(1)
  113. } else if a < b {
  114. Some(-1)
  115. } else if a > b {
  116. Some(1)
  117. } else {
  118. Some(0)
  119. }
  120. },
  121. "builtins::float::cmp::__ledf2(a, b)",
  122. );
  123. gen(
  124. |(a, b): (MyF32, MyF32)| {
  125. let (a, b) = (a.0, b.0);
  126. if a.is_nan() || b.is_nan() {
  127. return None;
  128. }
  129. if a.is_nan() || b.is_nan() {
  130. Some(1)
  131. } else if a < b {
  132. Some(-1)
  133. } else if a > b {
  134. Some(1)
  135. } else {
  136. Some(0)
  137. }
  138. },
  139. "builtins::float::cmp::__lesf2(a, b)",
  140. );
  141. gen(
  142. |(a, b): (MyF32, MyF32)| {
  143. let c = a.0.is_nan() || b.0.is_nan();
  144. Some(c as i32)
  145. },
  146. "builtins::float::cmp::__unordsf2(a, b)",
  147. );
  148. gen(
  149. |(a, b): (MyF64, MyF64)| {
  150. let c = a.0.is_nan() || b.0.is_nan();
  151. Some(c as i32)
  152. },
  153. "builtins::float::cmp::__unorddf2(a, b)",
  154. );
  155. if target_arch_arm {
  156. gen(
  157. |(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. "builtins::float::cmp::__aeabi_fcmple(a, b)",
  165. );
  166. gen(
  167. |(a, b): (MyF32, MyF32)| {
  168. if a.0.is_nan() || b.0.is_nan() {
  169. return None;
  170. }
  171. let c = (a.0 >= b.0) as i32;
  172. Some(c)
  173. },
  174. "builtins::float::cmp::__aeabi_fcmpge(a, b)",
  175. );
  176. gen(
  177. |(a, b): (MyF32, MyF32)| {
  178. if a.0.is_nan() || b.0.is_nan() {
  179. return None;
  180. }
  181. let c = (a.0 == b.0) as i32;
  182. Some(c)
  183. },
  184. "builtins::float::cmp::__aeabi_fcmpeq(a, b)",
  185. );
  186. gen(
  187. |(a, b): (MyF32, MyF32)| {
  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. "builtins::float::cmp::__aeabi_fcmplt(a, b)",
  195. );
  196. gen(
  197. |(a, b): (MyF32, MyF32)| {
  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. "builtins::float::cmp::__aeabi_fcmpgt(a, b)",
  205. );
  206. gen(
  207. |(a, b): (MyF64, MyF64)| {
  208. if a.0.is_nan() || b.0.is_nan() {
  209. return None;
  210. }
  211. let c = (a.0 <= b.0) as i32;
  212. Some(c)
  213. },
  214. "builtins::float::cmp::__aeabi_dcmple(a, b)",
  215. );
  216. gen(
  217. |(a, b): (MyF64, MyF64)| {
  218. if a.0.is_nan() || b.0.is_nan() {
  219. return None;
  220. }
  221. let c = (a.0 >= b.0) as i32;
  222. Some(c)
  223. },
  224. "builtins::float::cmp::__aeabi_dcmpge(a, b)",
  225. );
  226. gen(
  227. |(a, b): (MyF64, MyF64)| {
  228. if a.0.is_nan() || b.0.is_nan() {
  229. return None;
  230. }
  231. let c = (a.0 == b.0) as i32;
  232. Some(c)
  233. },
  234. "builtins::float::cmp::__aeabi_dcmpeq(a, b)",
  235. );
  236. gen(
  237. |(a, b): (MyF64, MyF64)| {
  238. if a.0.is_nan() || b.0.is_nan() {
  239. return None;
  240. }
  241. let c = (a.0 < b.0) as i32;
  242. Some(c)
  243. },
  244. "builtins::float::cmp::__aeabi_dcmplt(a, b)",
  245. );
  246. gen(
  247. |(a, b): (MyF64, MyF64)| {
  248. if a.0.is_nan() || b.0.is_nan() {
  249. return None;
  250. }
  251. let c = (a.0 > b.0) as i32;
  252. Some(c)
  253. },
  254. "builtins::float::cmp::__aeabi_dcmpgt(a, b)",
  255. );
  256. gen(
  257. |(a, b): (LargeF32, LargeF32)| {
  258. if a.0.is_nan() || b.0.is_nan() {
  259. return None;
  260. }
  261. Some((a.0 >= b.0) as i32)
  262. },
  263. "builtins::float::cmp::__gesf2vfp(a, b)",
  264. );
  265. gen(
  266. |(a, b): (MyF64, MyF64)| {
  267. if a.0.is_nan() || b.0.is_nan() {
  268. return None;
  269. }
  270. Some((a.0 >= b.0) as i32)
  271. },
  272. "builtins::float::cmp::__gedf2vfp(a, b)",
  273. );
  274. gen(
  275. |(a, b): (LargeF32, LargeF32)| {
  276. if a.0.is_nan() || b.0.is_nan() {
  277. return None;
  278. }
  279. Some((a.0 > b.0) as i32)
  280. },
  281. "builtins::float::cmp::__gtsf2vfp(a, b)",
  282. );
  283. gen(
  284. |(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. "builtins::float::cmp::__gtdf2vfp(a, b)",
  291. );
  292. gen(
  293. |(a, b): (LargeF32, LargeF32)| {
  294. if a.0.is_nan() || b.0.is_nan() {
  295. return None;
  296. }
  297. Some((a.0 < b.0) as i32)
  298. },
  299. "builtins::float::cmp::__ltsf2vfp(a, b)",
  300. );
  301. gen(
  302. |(a, b): (MyF64, MyF64)| {
  303. if a.0.is_nan() || b.0.is_nan() {
  304. return None;
  305. }
  306. Some((a.0 < b.0) as i32)
  307. },
  308. "builtins::float::cmp::__ltdf2vfp(a, b)",
  309. );
  310. gen(
  311. |(a, b): (LargeF32, LargeF32)| {
  312. if a.0.is_nan() || b.0.is_nan() {
  313. return None;
  314. }
  315. Some((a.0 <= b.0) as i32)
  316. },
  317. "builtins::float::cmp::__lesf2vfp(a, b)",
  318. );
  319. gen(
  320. |(a, b): (MyF64, MyF64)| {
  321. if a.0.is_nan() || b.0.is_nan() {
  322. return None;
  323. }
  324. Some((a.0 <= b.0) as i32)
  325. },
  326. "builtins::float::cmp::__ledf2vfp(a, b)",
  327. );
  328. gen(
  329. |(a, b): (LargeF32, LargeF32)| {
  330. if a.0.is_nan() || b.0.is_nan() {
  331. return None;
  332. }
  333. Some((a.0 != b.0) as i32)
  334. },
  335. "builtins::float::cmp::__nesf2vfp(a, b)",
  336. );
  337. gen(
  338. |(a, b): (MyF64, MyF64)| {
  339. if a.0.is_nan() || b.0.is_nan() {
  340. return None;
  341. }
  342. Some((a.0 != b.0) as i32)
  343. },
  344. "builtins::float::cmp::__nedf2vfp(a, b)",
  345. );
  346. gen(
  347. |(a, b): (LargeF32, LargeF32)| {
  348. if a.0.is_nan() || b.0.is_nan() {
  349. return None;
  350. }
  351. Some((a.0 == b.0) as i32)
  352. },
  353. "builtins::float::cmp::__eqsf2vfp(a, b)",
  354. );
  355. gen(
  356. |(a, b): (MyF64, MyF64)| {
  357. if a.0.is_nan() || b.0.is_nan() {
  358. return None;
  359. }
  360. Some((a.0 == b.0) as i32)
  361. },
  362. "builtins::float::cmp::__eqdf2vfp(a, b)",
  363. );
  364. }
  365. // float/extend.rs
  366. gen(
  367. |a: MyF32| {
  368. if a.0.is_nan() {
  369. return None;
  370. }
  371. Some(f64::from(a.0))
  372. },
  373. "builtins::float::extend::__extendsfdf2(a)",
  374. );
  375. if target_arch_arm {
  376. gen(
  377. |a: LargeF32| {
  378. if a.0.is_nan() {
  379. return None;
  380. }
  381. Some(f64::from(a.0))
  382. },
  383. "builtins::float::extend::__extendsfdf2vfp(a)",
  384. );
  385. }
  386. // float/conv.rs
  387. gen(
  388. |a: MyF64| i64::cast(a.0),
  389. "builtins::float::conv::__fixdfdi(a)",
  390. );
  391. gen(
  392. |a: MyF64| i32::cast(a.0),
  393. "builtins::float::conv::__fixdfsi(a)",
  394. );
  395. gen(
  396. |a: MyF32| i64::cast(a.0),
  397. "builtins::float::conv::__fixsfdi(a)",
  398. );
  399. gen(
  400. |a: MyF32| i32::cast(a.0),
  401. "builtins::float::conv::__fixsfsi(a)",
  402. );
  403. gen(
  404. |a: MyF32| i128::cast(a.0),
  405. "builtins::float::conv::__fixsfti(a)",
  406. );
  407. gen(
  408. |a: MyF64| i128::cast(a.0),
  409. "builtins::float::conv::__fixdfti(a)",
  410. );
  411. gen(
  412. |a: MyF64| u64::cast(a.0),
  413. "builtins::float::conv::__fixunsdfdi(a)",
  414. );
  415. gen(
  416. |a: MyF64| u32::cast(a.0),
  417. "builtins::float::conv::__fixunsdfsi(a)",
  418. );
  419. gen(
  420. |a: MyF32| u64::cast(a.0),
  421. "builtins::float::conv::__fixunssfdi(a)",
  422. );
  423. gen(
  424. |a: MyF32| u32::cast(a.0),
  425. "builtins::float::conv::__fixunssfsi(a)",
  426. );
  427. gen(
  428. |a: MyF32| u128::cast(a.0),
  429. "builtins::float::conv::__fixunssfti(a)",
  430. );
  431. gen(
  432. |a: MyF64| u128::cast(a.0),
  433. "builtins::float::conv::__fixunsdfti(a)",
  434. );
  435. gen(
  436. |a: MyI64| Some(a.0 as f64),
  437. "builtins::float::conv::__floatdidf(a)",
  438. );
  439. gen(
  440. |a: MyI32| Some(a.0 as f64),
  441. "builtins::float::conv::__floatsidf(a)",
  442. );
  443. gen(
  444. |a: MyI32| Some(a.0 as f32),
  445. "builtins::float::conv::__floatsisf(a)",
  446. );
  447. gen(
  448. |a: MyU64| Some(a.0 as f64),
  449. "builtins::float::conv::__floatundidf(a)",
  450. );
  451. gen(
  452. |a: MyU32| Some(a.0 as f64),
  453. "builtins::float::conv::__floatunsidf(a)",
  454. );
  455. gen(
  456. |a: MyU32| Some(a.0 as f32),
  457. "builtins::float::conv::__floatunsisf(a)",
  458. );
  459. gen(
  460. |a: MyU128| Some(a.0 as f32),
  461. "builtins::float::conv::__floatuntisf(a)",
  462. );
  463. if !target_arch_mips {
  464. gen(
  465. |a: MyI128| Some(a.0 as f32),
  466. "builtins::float::conv::__floattisf(a)",
  467. );
  468. gen(
  469. |a: MyI128| Some(a.0 as f64),
  470. "builtins::float::conv::__floattidf(a)",
  471. );
  472. gen(
  473. |a: MyU128| Some(a.0 as f64),
  474. "builtins::float::conv::__floatuntidf(a)",
  475. );
  476. }
  477. // float/pow.rs
  478. gen(
  479. |(a, b): (MyF64, MyI32)| {
  480. let c = a.0.powi(b.0);
  481. if a.0.is_nan() || c.is_nan() {
  482. None
  483. } else {
  484. Some(c)
  485. }
  486. },
  487. "builtins::float::pow::__powidf2(a, b)",
  488. );
  489. gen(
  490. |(a, b): (MyF32, MyI32)| {
  491. let c = a.0.powi(b.0);
  492. if a.0.is_nan() || c.is_nan() {
  493. None
  494. } else {
  495. Some(c)
  496. }
  497. },
  498. "builtins::float::pow::__powisf2(a, b)",
  499. );
  500. // float/sub.rs
  501. gen(
  502. |(a, b): (MyF64, MyF64)| {
  503. let c = a.0 - b.0;
  504. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  505. None
  506. } else {
  507. Some(c)
  508. }
  509. },
  510. "builtins::float::sub::__subdf3(a, b)",
  511. );
  512. gen(
  513. |(a, b): (MyF32, MyF32)| {
  514. let c = a.0 - b.0;
  515. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  516. None
  517. } else {
  518. Some(c)
  519. }
  520. },
  521. "builtins::float::sub::__subsf3(a, b)",
  522. );
  523. if target_arch_arm {
  524. gen(
  525. |(a, b): (MyF64, MyF64)| {
  526. let c = a.0 - b.0;
  527. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  528. None
  529. } else {
  530. Some(c)
  531. }
  532. },
  533. "builtins::float::sub::__subdf3vfp(a, b)",
  534. );
  535. gen(
  536. |(a, b): (LargeF32, LargeF32)| {
  537. let c = a.0 - b.0;
  538. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  539. None
  540. } else {
  541. Some(c)
  542. }
  543. },
  544. "builtins::float::sub::__subsf3vfp(a, b)",
  545. );
  546. }
  547. // float/mul.rs
  548. gen(
  549. |(a, b): (MyF64, MyF64)| {
  550. let c = a.0 * b.0;
  551. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  552. None
  553. } else {
  554. Some(c)
  555. }
  556. },
  557. "builtins::float::mul::__muldf3(a, b)",
  558. );
  559. gen(
  560. |(a, b): (LargeF32, LargeF32)| {
  561. let c = a.0 * b.0;
  562. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  563. None
  564. } else {
  565. Some(c)
  566. }
  567. },
  568. "builtins::float::mul::__mulsf3(a, b)",
  569. );
  570. if target_arch_arm {
  571. gen(
  572. |(a, b): (MyF64, MyF64)| {
  573. let c = a.0 * b.0;
  574. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  575. None
  576. } else {
  577. Some(c)
  578. }
  579. },
  580. "builtins::float::mul::__muldf3vfp(a, b)",
  581. );
  582. gen(
  583. |(a, b): (LargeF32, LargeF32)| {
  584. let c = a.0 * b.0;
  585. if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
  586. None
  587. } else {
  588. Some(c)
  589. }
  590. },
  591. "builtins::float::mul::__mulsf3vfp(a, b)",
  592. );
  593. }
  594. // float/div.rs
  595. gen(
  596. |(a, b): (MyF64, MyF64)| {
  597. if b.0 == 0.0 {
  598. return None;
  599. }
  600. let c = a.0 / b.0;
  601. if a.0.is_nan()
  602. || b.0.is_nan()
  603. || c.is_nan()
  604. || c.abs() <= f64::from_bits(4503599627370495u64)
  605. {
  606. None
  607. } else {
  608. Some(c)
  609. }
  610. },
  611. "builtins::float::div::__divdf3(a, b)",
  612. );
  613. gen(
  614. |(a, b): (LargeF32, LargeF32)| {
  615. if b.0 == 0.0 {
  616. return None;
  617. }
  618. let c = a.0 / b.0;
  619. if a.0.is_nan()
  620. || b.0.is_nan()
  621. || c.is_nan()
  622. || c.abs() <= f32::from_bits(16777215u32)
  623. {
  624. None
  625. } else {
  626. Some(c)
  627. }
  628. },
  629. "builtins::float::div::__divsf3(a, b)",
  630. );
  631. if target_arch_arm {
  632. gen(
  633. |(a, b): (MyF64, MyF64)| {
  634. if b.0 == 0.0 {
  635. return None;
  636. }
  637. let c = a.0 / b.0;
  638. if a.0.is_nan()
  639. || b.0.is_nan()
  640. || c.is_nan()
  641. || c.abs() <= f64::from_bits(4503599627370495u64)
  642. {
  643. None
  644. } else {
  645. Some(c)
  646. }
  647. },
  648. "builtins::float::div::__divdf3vfp(a, b)",
  649. );
  650. gen(
  651. |(a, b): (LargeF32, LargeF32)| {
  652. if b.0 == 0.0 {
  653. return None;
  654. }
  655. let c = a.0 / b.0;
  656. if a.0.is_nan()
  657. || b.0.is_nan()
  658. || c.is_nan()
  659. || c.abs() <= f32::from_bits(16777215u32)
  660. {
  661. None
  662. } else {
  663. Some(c)
  664. }
  665. },
  666. "builtins::float::div::__divsf3vfp(a, b)",
  667. );
  668. }
  669. // int/addsub.rs
  670. gen(
  671. |(a, b): (MyU128, MyU128)| Some(a.0.wrapping_add(b.0)),
  672. "builtins::int::addsub::__rust_u128_add(a, b)",
  673. );
  674. gen(
  675. |(a, b): (MyI128, MyI128)| Some(a.0.wrapping_add(b.0)),
  676. "builtins::int::addsub::__rust_i128_add(a, b)",
  677. );
  678. gen(
  679. |(a, b): (MyU128, MyU128)| Some(a.0.overflowing_add(b.0)),
  680. "builtins::int::addsub::__rust_u128_addo(a, b)",
  681. );
  682. gen(
  683. |(a, b): (MyI128, MyI128)| Some(a.0.overflowing_add(b.0)),
  684. "builtins::int::addsub::__rust_i128_addo(a, b)",
  685. );
  686. gen(
  687. |(a, b): (MyU128, MyU128)| Some(a.0.wrapping_sub(b.0)),
  688. "builtins::int::addsub::__rust_u128_sub(a, b)",
  689. );
  690. gen(
  691. |(a, b): (MyI128, MyI128)| Some(a.0.wrapping_sub(b.0)),
  692. "builtins::int::addsub::__rust_i128_sub(a, b)",
  693. );
  694. gen(
  695. |(a, b): (MyU128, MyU128)| Some(a.0.overflowing_sub(b.0)),
  696. "builtins::int::addsub::__rust_u128_subo(a, b)",
  697. );
  698. gen(
  699. |(a, b): (MyI128, MyI128)| Some(a.0.overflowing_sub(b.0)),
  700. "builtins::int::addsub::__rust_i128_subo(a, b)",
  701. );
  702. // int/mul.rs
  703. gen(
  704. |(a, b): (MyU64, MyU64)| Some(a.0.wrapping_mul(b.0)),
  705. "builtins::int::mul::__muldi3(a, b)",
  706. );
  707. gen(
  708. |(a, b): (MyI64, MyI64)| Some(a.0.overflowing_mul(b.0)),
  709. "{
  710. let mut o = 2;
  711. let c = builtins::int::mul::__mulodi4(a, b, &mut o);
  712. (c, match o { 0 => false, 1 => true, _ => panic!() })
  713. }",
  714. );
  715. gen(
  716. |(a, b): (MyI32, MyI32)| Some(a.0.overflowing_mul(b.0)),
  717. "{
  718. let mut o = 2;
  719. let c = builtins::int::mul::__mulosi4(a, b, &mut o);
  720. (c, match o { 0 => false, 1 => true, _ => panic!() })
  721. }",
  722. );
  723. gen(
  724. |(a, b): (MyI128, MyI128)| Some(a.0.wrapping_mul(b.0)),
  725. "builtins::int::mul::__multi3(a, b)",
  726. );
  727. gen(
  728. |(a, b): (MyI128, MyI128)| Some(a.0.overflowing_mul(b.0)),
  729. "{
  730. let mut o = 2;
  731. let c = builtins::int::mul::__muloti4(a, b, &mut o);
  732. (c, match o { 0 => false, 1 => true, _ => panic!() })
  733. }",
  734. );
  735. // int/sdiv.rs
  736. gen(
  737. |(a, b): (MyI64, MyI64)| {
  738. if b.0 == 0 {
  739. None
  740. } else {
  741. Some(a.0 / b.0)
  742. }
  743. },
  744. "builtins::int::sdiv::__divdi3(a, b)",
  745. );
  746. gen(
  747. |(a, b): (MyI64, MyI64)| {
  748. if b.0 == 0 {
  749. None
  750. } else {
  751. Some((a.0 / b.0, a.0 % b.0))
  752. }
  753. },
  754. "{
  755. let mut r = 0;
  756. (builtins::int::sdiv::__divmoddi4(a, b, &mut r), r)
  757. }",
  758. );
  759. gen(
  760. |(a, b): (MyI32, MyI32)| {
  761. if b.0 == 0 {
  762. None
  763. } else {
  764. Some((a.0 / b.0, a.0 % b.0))
  765. }
  766. },
  767. "{
  768. let mut r = 0;
  769. (builtins::int::sdiv::__divmodsi4(a, b, &mut r), r)
  770. }",
  771. );
  772. gen(
  773. |(a, b): (MyI128, MyI128)| {
  774. if b.0 == 0 {
  775. None
  776. } else {
  777. Some((a.0 / b.0, a.0 % b.0))
  778. }
  779. },
  780. "{
  781. let mut r = 0;
  782. (builtins::int::sdiv::__divmodti4(a, b, &mut r), r)
  783. }",
  784. );
  785. gen(
  786. |(a, b): (MyI32, MyI32)| {
  787. if b.0 == 0 {
  788. None
  789. } else {
  790. Some(a.0 / b.0)
  791. }
  792. },
  793. "builtins::int::sdiv::__divsi3(a, b)",
  794. );
  795. gen(
  796. |(a, b): (MyI32, MyI32)| {
  797. if b.0 == 0 {
  798. None
  799. } else {
  800. Some(a.0 % b.0)
  801. }
  802. },
  803. "builtins::int::sdiv::__modsi3(a, b)",
  804. );
  805. gen(
  806. |(a, b): (MyI64, MyI64)| {
  807. if b.0 == 0 {
  808. None
  809. } else {
  810. Some(a.0 % b.0)
  811. }
  812. },
  813. "builtins::int::sdiv::__moddi3(a, b)",
  814. );
  815. gen(
  816. |(a, b): (MyI128, MyI128)| {
  817. if b.0 == 0 {
  818. None
  819. } else {
  820. Some(a.0 / b.0)
  821. }
  822. },
  823. "builtins::int::sdiv::__divti3(a, b)",
  824. );
  825. gen(
  826. |(a, b): (MyI128, MyI128)| {
  827. if b.0 == 0 {
  828. None
  829. } else {
  830. Some(a.0 % b.0)
  831. }
  832. },
  833. "builtins::int::sdiv::__modti3(a, b)",
  834. );
  835. // int/shift.rs
  836. gen(
  837. |(a, b): (MyU32, MyU32)| Some(a.0 << (b.0 % 32)),
  838. "builtins::int::shift::__ashlsi3(a, b % 32)",
  839. );
  840. gen(
  841. |(a, b): (MyU64, MyU32)| Some(a.0 << (b.0 % 64)),
  842. "builtins::int::shift::__ashldi3(a, b % 64)",
  843. );
  844. gen(
  845. |(a, b): (MyU128, MyU32)| Some(a.0 << (b.0 % 128)),
  846. "builtins::int::shift::__ashlti3(a, b % 128)",
  847. );
  848. gen(
  849. |(a, b): (MyI32, MyU32)| Some(a.0 >> (b.0 % 32)),
  850. "builtins::int::shift::__ashrsi3(a, b % 32)",
  851. );
  852. gen(
  853. |(a, b): (MyI64, MyU32)| Some(a.0 >> (b.0 % 64)),
  854. "builtins::int::shift::__ashrdi3(a, b % 64)",
  855. );
  856. gen(
  857. |(a, b): (MyI128, MyU32)| Some(a.0 >> (b.0 % 128)),
  858. "builtins::int::shift::__ashrti3(a, b % 128)",
  859. );
  860. gen(
  861. |(a, b): (MyU32, MyU32)| Some(a.0 >> (b.0 % 32)),
  862. "builtins::int::shift::__lshrsi3(a, b % 32)",
  863. );
  864. gen(
  865. |(a, b): (MyU64, MyU32)| Some(a.0 >> (b.0 % 64)),
  866. "builtins::int::shift::__lshrdi3(a, b % 64)",
  867. );
  868. gen(
  869. |(a, b): (MyU128, MyU32)| Some(a.0 >> (b.0 % 128)),
  870. "builtins::int::shift::__lshrti3(a, b % 128)",
  871. );
  872. // int/udiv.rs
  873. gen(
  874. |(a, b): (MyU64, MyU64)| {
  875. if b.0 == 0 {
  876. None
  877. } else {
  878. Some(a.0 / b.0)
  879. }
  880. },
  881. "builtins::int::udiv::__udivdi3(a, b)",
  882. );
  883. gen(
  884. |(a, b): (MyU64, MyU64)| {
  885. if b.0 == 0 {
  886. None
  887. } else {
  888. Some((a.0 / b.0, a.0 % b.0))
  889. }
  890. },
  891. "{
  892. let mut r = 0;
  893. (builtins::int::udiv::__udivmoddi4(a, b, Some(&mut r)), r)
  894. }",
  895. );
  896. gen(
  897. |(a, b): (MyU32, MyU32)| {
  898. if b.0 == 0 {
  899. None
  900. } else {
  901. Some((a.0 / b.0, a.0 % b.0))
  902. }
  903. },
  904. "{
  905. let mut r = 0;
  906. (builtins::int::udiv::__udivmodsi4(a, b, Some(&mut r)), r)
  907. }",
  908. );
  909. gen(
  910. |(a, b): (MyU32, MyU32)| {
  911. if b.0 == 0 {
  912. None
  913. } else {
  914. Some(a.0 / b.0)
  915. }
  916. },
  917. "builtins::int::udiv::__udivsi3(a, b)",
  918. );
  919. gen(
  920. |(a, b): (MyU32, MyU32)| {
  921. if b.0 == 0 {
  922. None
  923. } else {
  924. Some(a.0 % b.0)
  925. }
  926. },
  927. "builtins::int::udiv::__umodsi3(a, b)",
  928. );
  929. gen(
  930. |(a, b): (MyU64, MyU64)| {
  931. if b.0 == 0 {
  932. None
  933. } else {
  934. Some(a.0 % b.0)
  935. }
  936. },
  937. "builtins::int::udiv::__umoddi3(a, b)",
  938. );
  939. gen(
  940. |(a, b): (MyU128, MyU128)| {
  941. if b.0 == 0 {
  942. None
  943. } else {
  944. Some(a.0 / b.0)
  945. }
  946. },
  947. "builtins::int::udiv::__udivti3(a, b)",
  948. );
  949. gen(
  950. |(a, b): (MyU128, MyU128)| {
  951. if b.0 == 0 {
  952. None
  953. } else {
  954. Some(a.0 % b.0)
  955. }
  956. },
  957. "builtins::int::udiv::__umodti3(a, b)",
  958. );
  959. gen(
  960. |(a, b): (MyU128, MyU128)| {
  961. if b.0 == 0 {
  962. None
  963. } else {
  964. Some((a.0 / b.0, a.0 % b.0))
  965. }
  966. },
  967. "{
  968. let mut r = 0;
  969. (builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r)
  970. }",
  971. );
  972. }
  973. macro_rules! gen_float {
  974. ($name:ident,
  975. $fty:ident,
  976. $uty:ident,
  977. $bits:expr,
  978. $significand_bits:expr) => {
  979. pub fn $name<R>(rng: &mut R) -> $fty
  980. where
  981. R: Rng + ?Sized,
  982. {
  983. const BITS: u8 = $bits;
  984. const SIGNIFICAND_BITS: u8 = $significand_bits;
  985. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  986. const SIGN_MASK: $uty = (1 << (BITS - 1));
  987. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  988. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  989. unsafe {
  990. mem::transmute(
  991. ((sign as $uty) << (BITS - 1))
  992. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  993. | (significand & SIGNIFICAND_MASK),
  994. )
  995. }
  996. }
  997. if rng.gen_range(0, 10) == 1 {
  998. // Special values
  999. *[
  1000. -0.0,
  1001. 0.0,
  1002. ::std::$fty::MIN,
  1003. ::std::$fty::MIN_POSITIVE,
  1004. ::std::$fty::MAX,
  1005. ::std::$fty::NAN,
  1006. ::std::$fty::INFINITY,
  1007. -::std::$fty::INFINITY,
  1008. ]
  1009. .choose(rng)
  1010. .unwrap()
  1011. } else if rng.gen_range(0, 10) == 1 {
  1012. // NaN patterns
  1013. mk_f32(rng.gen(), rng.gen(), 0)
  1014. } else if rng.gen() {
  1015. // Denormalized
  1016. mk_f32(rng.gen(), 0, rng.gen())
  1017. } else {
  1018. // Random anything
  1019. mk_f32(rng.gen(), rng.gen(), rng.gen())
  1020. }
  1021. }
  1022. };
  1023. }
  1024. gen_float!(gen_f32, f32, u32, 32, 23);
  1025. gen_float!(gen_f64, f64, u64, 64, 52);
  1026. macro_rules! gen_large_float {
  1027. ($name:ident,
  1028. $fty:ident,
  1029. $uty:ident,
  1030. $bits:expr,
  1031. $significand_bits:expr) => {
  1032. pub fn $name<R>(rng: &mut R) -> $fty
  1033. where
  1034. R: Rng + ?Sized,
  1035. {
  1036. const BITS: u8 = $bits;
  1037. const SIGNIFICAND_BITS: u8 = $significand_bits;
  1038. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  1039. const SIGN_MASK: $uty = (1 << (BITS - 1));
  1040. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  1041. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  1042. unsafe {
  1043. mem::transmute(
  1044. ((sign as $uty) << (BITS - 1))
  1045. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  1046. | (significand & SIGNIFICAND_MASK),
  1047. )
  1048. }
  1049. }
  1050. if rng.gen_range(0, 10) == 1 {
  1051. // Special values
  1052. *[
  1053. -0.0,
  1054. 0.0,
  1055. ::std::$fty::MIN,
  1056. ::std::$fty::MIN_POSITIVE,
  1057. ::std::$fty::MAX,
  1058. ::std::$fty::NAN,
  1059. ::std::$fty::INFINITY,
  1060. -::std::$fty::INFINITY,
  1061. ]
  1062. .choose(rng)
  1063. .unwrap()
  1064. } else if rng.gen_range(0, 10) == 1 {
  1065. // NaN patterns
  1066. mk_f32(rng.gen(), rng.gen(), 0)
  1067. } else if rng.gen() {
  1068. // Denormalized
  1069. mk_f32(rng.gen(), 0, rng.gen())
  1070. } else {
  1071. // Random anything
  1072. rng.gen::<$fty>()
  1073. }
  1074. }
  1075. };
  1076. }
  1077. gen_large_float!(gen_large_f32, f32, u32, 32, 23);
  1078. gen_large_float!(gen_large_f64, f64, u64, 64, 52);
  1079. trait TestInput: Hash + Eq + fmt::Debug {
  1080. fn ty_name() -> String;
  1081. fn generate_lets(container: &str, cnt: &mut u8) -> String;
  1082. fn generate_static(&self, dst: &mut String);
  1083. }
  1084. trait TestOutput {
  1085. fn ty_name() -> String;
  1086. fn generate_static(&self, dst: &mut String);
  1087. fn generate_expr(container: &str) -> String;
  1088. }
  1089. fn gen<F, A, R>(mut generate: F, test: &str)
  1090. where
  1091. F: FnMut(A) -> Option<R>,
  1092. A: TestInput + Copy,
  1093. R: TestOutput,
  1094. rand::distributions::Standard: rand::distributions::Distribution<A>,
  1095. {
  1096. let rng = &mut rand::thread_rng();
  1097. let testname = test.split("::").last().unwrap().split("(").next().unwrap();
  1098. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  1099. let out_file = out_dir.join("generated.rs");
  1100. let mut testcases = HashMap::new();
  1101. let mut n = NTESTS;
  1102. while n > 0 {
  1103. let input: A = rng.gen();
  1104. if testcases.contains_key(&input) {
  1105. continue;
  1106. }
  1107. let output = match generate(input) {
  1108. Some(o) => o,
  1109. None => continue,
  1110. };
  1111. testcases.insert(input, output);
  1112. n -= 1;
  1113. }
  1114. let mut contents = String::new();
  1115. contents.push_str(&format!("mod {} {{\nuse super::*;\n", testname));
  1116. contents.push_str("#[test]\n");
  1117. contents.push_str("fn test() {\n");
  1118. contents.push_str(&format!(
  1119. "static TESTS: [({}, {}); {}] = [\n",
  1120. A::ty_name(),
  1121. R::ty_name(),
  1122. NTESTS
  1123. ));
  1124. for (input, output) in testcases {
  1125. contents.push_str(" (");
  1126. input.generate_static(&mut contents);
  1127. contents.push_str(", ");
  1128. output.generate_static(&mut contents);
  1129. contents.push_str("),\n");
  1130. }
  1131. contents.push_str("];\n");
  1132. contents.push_str(&format!(
  1133. r#"
  1134. for &(inputs, output) in TESTS.iter() {{
  1135. {}
  1136. assert_eq!({}, {}, "inputs {{:?}}", inputs)
  1137. }}
  1138. "#,
  1139. A::generate_lets("inputs", &mut 0),
  1140. R::generate_expr("output"),
  1141. test,
  1142. ));
  1143. contents.push_str("\n}\n");
  1144. contents.push_str("\n}\n");
  1145. OpenOptions::new()
  1146. .write(true)
  1147. .append(true)
  1148. .create(true)
  1149. .open(out_file)
  1150. .unwrap()
  1151. .write_all(contents.as_bytes())
  1152. .unwrap();
  1153. }
  1154. macro_rules! my_float {
  1155. ($(struct $name:ident($inner:ident) = $gen:ident;)*) => ($(
  1156. #[derive(Debug, Clone, Copy)]
  1157. struct $name($inner);
  1158. impl TestInput for $name {
  1159. fn ty_name() -> String {
  1160. format!("u{}", &stringify!($inner)[1..])
  1161. }
  1162. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1163. let me = *cnt;
  1164. *cnt += 1;
  1165. format!("let {} = {}::from_bits({});\n",
  1166. (b'a' + me) as char,
  1167. stringify!($inner),
  1168. container)
  1169. }
  1170. fn generate_static(&self, dst: &mut String) {
  1171. write!(dst, "{}", self.0.to_bits()).unwrap();
  1172. }
  1173. }
  1174. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1175. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1176. $name($gen(r))
  1177. }
  1178. }
  1179. impl Hash for $name {
  1180. fn hash<H: Hasher>(&self, h: &mut H) {
  1181. self.0.to_bits().hash(h)
  1182. }
  1183. }
  1184. impl PartialEq for $name {
  1185. fn eq(&self, other: &$name) -> bool {
  1186. self.0.to_bits() == other.0.to_bits()
  1187. }
  1188. }
  1189. impl Eq for $name {}
  1190. )*)
  1191. }
  1192. my_float! {
  1193. struct MyF64(f64) = gen_f64;
  1194. struct LargeF64(f64) = gen_large_f64;
  1195. struct MyF32(f32) = gen_f32;
  1196. struct LargeF32(f32) = gen_large_f32;
  1197. }
  1198. macro_rules! my_integer {
  1199. ($(struct $name:ident($inner:ident);)*) => ($(
  1200. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
  1201. struct $name($inner);
  1202. impl TestInput for $name {
  1203. fn ty_name() -> String {
  1204. stringify!($inner).to_string()
  1205. }
  1206. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1207. let me = *cnt;
  1208. *cnt += 1;
  1209. format!("let {} = {};\n",
  1210. (b'a' + me) as char,
  1211. container)
  1212. }
  1213. fn generate_static(&self, dst: &mut String) {
  1214. write!(dst, "{}", self.0).unwrap();
  1215. }
  1216. }
  1217. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1218. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1219. let bits = (0 as $inner).count_zeros();
  1220. let mut mk = || {
  1221. if r.gen_range(0, 10) == 1 {
  1222. *[
  1223. ::std::$inner::MAX >> (bits / 2),
  1224. 0,
  1225. ::std::$inner::MIN >> (bits / 2),
  1226. ].choose(r).unwrap()
  1227. } else {
  1228. r.gen::<$inner>()
  1229. }
  1230. };
  1231. let a = mk();
  1232. let b = mk();
  1233. $name((a << (bits / 2)) | (b & (!0 << (bits / 2))))
  1234. }
  1235. }
  1236. )*)
  1237. }
  1238. my_integer! {
  1239. struct MyI32(i32);
  1240. struct MyI64(i64);
  1241. struct MyI128(i128);
  1242. struct MyU16(u16);
  1243. struct MyU32(u32);
  1244. struct MyU64(u64);
  1245. struct MyU128(u128);
  1246. }
  1247. impl<A, B> TestInput for (A, B)
  1248. where
  1249. A: TestInput,
  1250. B: TestInput,
  1251. {
  1252. fn ty_name() -> String {
  1253. format!("({}, {})", A::ty_name(), B::ty_name())
  1254. }
  1255. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1256. format!(
  1257. "{}{}",
  1258. A::generate_lets(&format!("{}.0", container), cnt),
  1259. B::generate_lets(&format!("{}.1", container), cnt)
  1260. )
  1261. }
  1262. fn generate_static(&self, dst: &mut String) {
  1263. dst.push_str("(");
  1264. self.0.generate_static(dst);
  1265. dst.push_str(", ");
  1266. self.1.generate_static(dst);
  1267. dst.push_str(")");
  1268. }
  1269. }
  1270. impl TestOutput for f64 {
  1271. fn ty_name() -> String {
  1272. "u64".to_string()
  1273. }
  1274. fn generate_static(&self, dst: &mut String) {
  1275. write!(dst, "{}", self.to_bits()).unwrap();
  1276. }
  1277. fn generate_expr(container: &str) -> String {
  1278. format!("f64::from_bits({})", container)
  1279. }
  1280. }
  1281. impl TestOutput for f32 {
  1282. fn ty_name() -> String {
  1283. "u32".to_string()
  1284. }
  1285. fn generate_static(&self, dst: &mut String) {
  1286. write!(dst, "{}", self.to_bits()).unwrap();
  1287. }
  1288. fn generate_expr(container: &str) -> String {
  1289. format!("f32::from_bits({})", container)
  1290. }
  1291. }
  1292. macro_rules! plain_test_output {
  1293. ($($i:tt)*) => ($(
  1294. impl TestOutput for $i {
  1295. fn ty_name() -> String {
  1296. stringify!($i).to_string()
  1297. }
  1298. fn generate_static(&self, dst: &mut String) {
  1299. write!(dst, "{}", self).unwrap();
  1300. }
  1301. fn generate_expr(container: &str) -> String {
  1302. container.to_string()
  1303. }
  1304. }
  1305. )*)
  1306. }
  1307. plain_test_output!(i32 i64 i128 u32 u64 u128 bool);
  1308. impl<A, B> TestOutput for (A, B)
  1309. where
  1310. A: TestOutput,
  1311. B: TestOutput,
  1312. {
  1313. fn ty_name() -> String {
  1314. format!("({}, {})", A::ty_name(), B::ty_name())
  1315. }
  1316. fn generate_static(&self, dst: &mut String) {
  1317. dst.push_str("(");
  1318. self.0.generate_static(dst);
  1319. dst.push_str(", ");
  1320. self.1.generate_static(dst);
  1321. dst.push_str(")");
  1322. }
  1323. fn generate_expr(container: &str) -> String {
  1324. container.to_string()
  1325. }
  1326. }
  1327. trait FromFloat<T>: Sized {
  1328. fn cast(src: T) -> Option<Self>;
  1329. }
  1330. macro_rules! from_float {
  1331. ($($src:ident => $($dst:ident),+);+;) => {
  1332. $(
  1333. $(
  1334. impl FromFloat<$src> for $dst {
  1335. fn cast(src: $src) -> Option<$dst> {
  1336. use std::{$dst, $src};
  1337. if src.is_nan() ||
  1338. src.is_infinite() ||
  1339. src < std::$dst::MIN as $src ||
  1340. src > std::$dst::MAX as $src
  1341. {
  1342. None
  1343. } else {
  1344. Some(src as $dst)
  1345. }
  1346. }
  1347. }
  1348. )+
  1349. )+
  1350. }
  1351. }
  1352. from_float! {
  1353. f32 => i32, i64, i128, u32, u64, u128;
  1354. f64 => i32, i64, i128, u32, u64, u128;
  1355. }