build.rs 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433
  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() <= unsafe { mem::transmute(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() <= unsafe { mem::transmute(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() <= unsafe { mem::transmute(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() <= unsafe { mem::transmute(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): (MyI32, MyI32)| {
  774. if b.0 == 0 {
  775. None
  776. } else {
  777. Some(a.0 / b.0)
  778. }
  779. },
  780. "builtins::int::sdiv::__divsi3(a, b)",
  781. );
  782. gen(
  783. |(a, b): (MyI32, MyI32)| {
  784. if b.0 == 0 {
  785. None
  786. } else {
  787. Some(a.0 % b.0)
  788. }
  789. },
  790. "builtins::int::sdiv::__modsi3(a, b)",
  791. );
  792. gen(
  793. |(a, b): (MyI64, MyI64)| {
  794. if b.0 == 0 {
  795. None
  796. } else {
  797. Some(a.0 % b.0)
  798. }
  799. },
  800. "builtins::int::sdiv::__moddi3(a, b)",
  801. );
  802. gen(
  803. |(a, b): (MyI128, MyI128)| {
  804. if b.0 == 0 {
  805. None
  806. } else {
  807. Some(a.0 / b.0)
  808. }
  809. },
  810. "builtins::int::sdiv::__divti3(a, b)",
  811. );
  812. gen(
  813. |(a, b): (MyI128, MyI128)| {
  814. if b.0 == 0 {
  815. None
  816. } else {
  817. Some(a.0 % b.0)
  818. }
  819. },
  820. "builtins::int::sdiv::__modti3(a, b)",
  821. );
  822. // int/shift.rs
  823. gen(
  824. |(a, b): (MyU32, MyU32)| Some(a.0 << (b.0 % 32)),
  825. "builtins::int::shift::__ashlsi3(a, b % 32)",
  826. );
  827. gen(
  828. |(a, b): (MyU64, MyU32)| Some(a.0 << (b.0 % 64)),
  829. "builtins::int::shift::__ashldi3(a, b % 64)",
  830. );
  831. gen(
  832. |(a, b): (MyU128, MyU32)| Some(a.0 << (b.0 % 128)),
  833. "builtins::int::shift::__ashlti3(a, b % 128)",
  834. );
  835. gen(
  836. |(a, b): (MyI32, MyU32)| Some(a.0 >> (b.0 % 32)),
  837. "builtins::int::shift::__ashrsi3(a, b % 32)",
  838. );
  839. gen(
  840. |(a, b): (MyI64, MyU32)| Some(a.0 >> (b.0 % 64)),
  841. "builtins::int::shift::__ashrdi3(a, b % 64)",
  842. );
  843. gen(
  844. |(a, b): (MyI128, MyU32)| Some(a.0 >> (b.0 % 128)),
  845. "builtins::int::shift::__ashrti3(a, b % 128)",
  846. );
  847. gen(
  848. |(a, b): (MyU32, MyU32)| Some(a.0 >> (b.0 % 32)),
  849. "builtins::int::shift::__lshrsi3(a, b % 32)",
  850. );
  851. gen(
  852. |(a, b): (MyU64, MyU32)| Some(a.0 >> (b.0 % 64)),
  853. "builtins::int::shift::__lshrdi3(a, b % 64)",
  854. );
  855. gen(
  856. |(a, b): (MyU128, MyU32)| Some(a.0 >> (b.0 % 128)),
  857. "builtins::int::shift::__lshrti3(a, b % 128)",
  858. );
  859. // int/udiv.rs
  860. gen(
  861. |(a, b): (MyU64, MyU64)| {
  862. if b.0 == 0 {
  863. None
  864. } else {
  865. Some(a.0 / b.0)
  866. }
  867. },
  868. "builtins::int::udiv::__udivdi3(a, b)",
  869. );
  870. gen(
  871. |(a, b): (MyU64, MyU64)| {
  872. if b.0 == 0 {
  873. None
  874. } else {
  875. Some((a.0 / b.0, a.0 % b.0))
  876. }
  877. },
  878. "{
  879. let mut r = 0;
  880. (builtins::int::udiv::__udivmoddi4(a, b, Some(&mut r)), r)
  881. }",
  882. );
  883. gen(
  884. |(a, b): (MyU32, MyU32)| {
  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::__udivmodsi4(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)
  902. }
  903. },
  904. "builtins::int::udiv::__udivsi3(a, b)",
  905. );
  906. gen(
  907. |(a, b): (MyU32, MyU32)| {
  908. if b.0 == 0 {
  909. None
  910. } else {
  911. Some(a.0 % b.0)
  912. }
  913. },
  914. "builtins::int::udiv::__umodsi3(a, b)",
  915. );
  916. gen(
  917. |(a, b): (MyU64, MyU64)| {
  918. if b.0 == 0 {
  919. None
  920. } else {
  921. Some(a.0 % b.0)
  922. }
  923. },
  924. "builtins::int::udiv::__umoddi3(a, b)",
  925. );
  926. gen(
  927. |(a, b): (MyU128, MyU128)| {
  928. if b.0 == 0 {
  929. None
  930. } else {
  931. Some(a.0 / b.0)
  932. }
  933. },
  934. "builtins::int::udiv::__udivti3(a, b)",
  935. );
  936. gen(
  937. |(a, b): (MyU128, MyU128)| {
  938. if b.0 == 0 {
  939. None
  940. } else {
  941. Some(a.0 % b.0)
  942. }
  943. },
  944. "builtins::int::udiv::__umodti3(a, b)",
  945. );
  946. gen(
  947. |(a, b): (MyU128, MyU128)| {
  948. if b.0 == 0 {
  949. None
  950. } else {
  951. Some((a.0 / b.0, a.0 % b.0))
  952. }
  953. },
  954. "{
  955. let mut r = 0;
  956. (builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r)
  957. }",
  958. );
  959. }
  960. macro_rules! gen_float {
  961. ($name:ident,
  962. $fty:ident,
  963. $uty:ident,
  964. $bits:expr,
  965. $significand_bits:expr) => {
  966. pub fn $name<R>(rng: &mut R) -> $fty
  967. where
  968. R: Rng + ?Sized,
  969. {
  970. const BITS: u8 = $bits;
  971. const SIGNIFICAND_BITS: u8 = $significand_bits;
  972. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  973. const SIGN_MASK: $uty = (1 << (BITS - 1));
  974. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  975. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  976. unsafe {
  977. mem::transmute(
  978. ((sign as $uty) << (BITS - 1))
  979. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  980. | (significand & SIGNIFICAND_MASK),
  981. )
  982. }
  983. }
  984. if rng.gen_range(0, 10) == 1 {
  985. // Special values
  986. *[
  987. -0.0,
  988. 0.0,
  989. ::std::$fty::MIN,
  990. ::std::$fty::MIN_POSITIVE,
  991. ::std::$fty::MAX,
  992. ::std::$fty::NAN,
  993. ::std::$fty::INFINITY,
  994. -::std::$fty::INFINITY,
  995. ]
  996. .choose(rng)
  997. .unwrap()
  998. } else if rng.gen_range(0, 10) == 1 {
  999. // NaN patterns
  1000. mk_f32(rng.gen(), rng.gen(), 0)
  1001. } else if rng.gen() {
  1002. // Denormalized
  1003. mk_f32(rng.gen(), 0, rng.gen())
  1004. } else {
  1005. // Random anything
  1006. mk_f32(rng.gen(), rng.gen(), rng.gen())
  1007. }
  1008. }
  1009. };
  1010. }
  1011. gen_float!(gen_f32, f32, u32, 32, 23);
  1012. gen_float!(gen_f64, f64, u64, 64, 52);
  1013. macro_rules! gen_large_float {
  1014. ($name:ident,
  1015. $fty:ident,
  1016. $uty:ident,
  1017. $bits:expr,
  1018. $significand_bits:expr) => {
  1019. pub fn $name<R>(rng: &mut R) -> $fty
  1020. where
  1021. R: Rng + ?Sized,
  1022. {
  1023. const BITS: u8 = $bits;
  1024. const SIGNIFICAND_BITS: u8 = $significand_bits;
  1025. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  1026. const SIGN_MASK: $uty = (1 << (BITS - 1));
  1027. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  1028. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  1029. unsafe {
  1030. mem::transmute(
  1031. ((sign as $uty) << (BITS - 1))
  1032. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  1033. | (significand & SIGNIFICAND_MASK),
  1034. )
  1035. }
  1036. }
  1037. if rng.gen_range(0, 10) == 1 {
  1038. // Special values
  1039. *[
  1040. -0.0,
  1041. 0.0,
  1042. ::std::$fty::MIN,
  1043. ::std::$fty::MIN_POSITIVE,
  1044. ::std::$fty::MAX,
  1045. ::std::$fty::NAN,
  1046. ::std::$fty::INFINITY,
  1047. -::std::$fty::INFINITY,
  1048. ]
  1049. .choose(rng)
  1050. .unwrap()
  1051. } else if rng.gen_range(0, 10) == 1 {
  1052. // NaN patterns
  1053. mk_f32(rng.gen(), rng.gen(), 0)
  1054. } else if rng.gen() {
  1055. // Denormalized
  1056. mk_f32(rng.gen(), 0, rng.gen())
  1057. } else {
  1058. // Random anything
  1059. rng.gen::<$fty>()
  1060. }
  1061. }
  1062. };
  1063. }
  1064. gen_large_float!(gen_large_f32, f32, u32, 32, 23);
  1065. gen_large_float!(gen_large_f64, f64, u64, 64, 52);
  1066. trait TestInput: Hash + Eq + fmt::Debug {
  1067. fn ty_name() -> String;
  1068. fn generate_lets(container: &str, cnt: &mut u8) -> String;
  1069. fn generate_static(&self, dst: &mut String);
  1070. }
  1071. trait TestOutput {
  1072. fn ty_name() -> String;
  1073. fn generate_static(&self, dst: &mut String);
  1074. fn generate_expr(container: &str) -> String;
  1075. }
  1076. fn gen<F, A, R>(mut generate: F, test: &str)
  1077. where
  1078. F: FnMut(A) -> Option<R>,
  1079. A: TestInput + Copy,
  1080. R: TestOutput,
  1081. rand::distributions::Standard: rand::distributions::Distribution<A>,
  1082. {
  1083. let rng = &mut rand::thread_rng();
  1084. let testname = test.split("::").last().unwrap().split("(").next().unwrap();
  1085. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  1086. let out_file = out_dir.join("generated.rs");
  1087. let mut testcases = HashMap::new();
  1088. let mut n = NTESTS;
  1089. while n > 0 {
  1090. let input: A = rng.gen();
  1091. if testcases.contains_key(&input) {
  1092. continue;
  1093. }
  1094. let output = match generate(input) {
  1095. Some(o) => o,
  1096. None => continue,
  1097. };
  1098. testcases.insert(input, output);
  1099. n -= 1;
  1100. }
  1101. let mut contents = String::new();
  1102. contents.push_str(&format!("mod {} {{\nuse super::*;\n", testname));
  1103. contents.push_str("#[test]\n");
  1104. contents.push_str("fn test() {\n");
  1105. contents.push_str(&format!(
  1106. "static TESTS: [({}, {}); {}] = [\n",
  1107. A::ty_name(),
  1108. R::ty_name(),
  1109. NTESTS
  1110. ));
  1111. for (input, output) in testcases {
  1112. contents.push_str(" (");
  1113. input.generate_static(&mut contents);
  1114. contents.push_str(", ");
  1115. output.generate_static(&mut contents);
  1116. contents.push_str("),\n");
  1117. }
  1118. contents.push_str("];\n");
  1119. contents.push_str(&format!(
  1120. r#"
  1121. for &(inputs, output) in TESTS.iter() {{
  1122. {}
  1123. assert_eq!({}, {}, "inputs {{:?}}", inputs)
  1124. }}
  1125. "#,
  1126. A::generate_lets("inputs", &mut 0),
  1127. R::generate_expr("output"),
  1128. test,
  1129. ));
  1130. contents.push_str("\n}\n");
  1131. contents.push_str("\n}\n");
  1132. OpenOptions::new()
  1133. .write(true)
  1134. .append(true)
  1135. .create(true)
  1136. .open(out_file)
  1137. .unwrap()
  1138. .write_all(contents.as_bytes())
  1139. .unwrap();
  1140. }
  1141. macro_rules! my_float {
  1142. ($(struct $name:ident($inner:ident) = $gen:ident;)*) => ($(
  1143. #[derive(Debug, Clone, Copy)]
  1144. struct $name($inner);
  1145. impl TestInput for $name {
  1146. fn ty_name() -> String {
  1147. format!("u{}", &stringify!($inner)[1..])
  1148. }
  1149. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1150. let me = *cnt;
  1151. *cnt += 1;
  1152. format!("let {} = {}::from_bits({});\n",
  1153. (b'a' + me) as char,
  1154. stringify!($inner),
  1155. container)
  1156. }
  1157. fn generate_static(&self, dst: &mut String) {
  1158. write!(dst, "{}", self.0.to_bits()).unwrap();
  1159. }
  1160. }
  1161. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1162. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1163. $name($gen(r))
  1164. }
  1165. }
  1166. impl Hash for $name {
  1167. fn hash<H: Hasher>(&self, h: &mut H) {
  1168. self.0.to_bits().hash(h)
  1169. }
  1170. }
  1171. impl PartialEq for $name {
  1172. fn eq(&self, other: &$name) -> bool {
  1173. self.0.to_bits() == other.0.to_bits()
  1174. }
  1175. }
  1176. impl Eq for $name {}
  1177. )*)
  1178. }
  1179. my_float! {
  1180. struct MyF64(f64) = gen_f64;
  1181. struct LargeF64(f64) = gen_large_f64;
  1182. struct MyF32(f32) = gen_f32;
  1183. struct LargeF32(f32) = gen_large_f32;
  1184. }
  1185. macro_rules! my_integer {
  1186. ($(struct $name:ident($inner:ident);)*) => ($(
  1187. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
  1188. struct $name($inner);
  1189. impl TestInput for $name {
  1190. fn ty_name() -> String {
  1191. stringify!($inner).to_string()
  1192. }
  1193. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1194. let me = *cnt;
  1195. *cnt += 1;
  1196. format!("let {} = {};\n",
  1197. (b'a' + me) as char,
  1198. container)
  1199. }
  1200. fn generate_static(&self, dst: &mut String) {
  1201. write!(dst, "{}", self.0).unwrap();
  1202. }
  1203. }
  1204. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1205. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1206. let bits = (0 as $inner).count_zeros();
  1207. let mut mk = || {
  1208. if r.gen_range(0, 10) == 1 {
  1209. *[
  1210. ::std::$inner::MAX >> (bits / 2),
  1211. 0,
  1212. ::std::$inner::MIN >> (bits / 2),
  1213. ].choose(r).unwrap()
  1214. } else {
  1215. r.gen::<$inner>()
  1216. }
  1217. };
  1218. let a = mk();
  1219. let b = mk();
  1220. $name((a << (bits / 2)) | (b & (!0 << (bits / 2))))
  1221. }
  1222. }
  1223. )*)
  1224. }
  1225. my_integer! {
  1226. struct MyI32(i32);
  1227. struct MyI64(i64);
  1228. struct MyI128(i128);
  1229. struct MyU16(u16);
  1230. struct MyU32(u32);
  1231. struct MyU64(u64);
  1232. struct MyU128(u128);
  1233. }
  1234. impl<A, B> TestInput for (A, B)
  1235. where
  1236. A: TestInput,
  1237. B: TestInput,
  1238. {
  1239. fn ty_name() -> String {
  1240. format!("({}, {})", A::ty_name(), B::ty_name())
  1241. }
  1242. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1243. format!(
  1244. "{}{}",
  1245. A::generate_lets(&format!("{}.0", container), cnt),
  1246. B::generate_lets(&format!("{}.1", container), cnt)
  1247. )
  1248. }
  1249. fn generate_static(&self, dst: &mut String) {
  1250. dst.push_str("(");
  1251. self.0.generate_static(dst);
  1252. dst.push_str(", ");
  1253. self.1.generate_static(dst);
  1254. dst.push_str(")");
  1255. }
  1256. }
  1257. impl TestOutput for f64 {
  1258. fn ty_name() -> String {
  1259. "u64".to_string()
  1260. }
  1261. fn generate_static(&self, dst: &mut String) {
  1262. write!(dst, "{}", self.to_bits()).unwrap();
  1263. }
  1264. fn generate_expr(container: &str) -> String {
  1265. format!("f64::from_bits({})", container)
  1266. }
  1267. }
  1268. impl TestOutput for f32 {
  1269. fn ty_name() -> String {
  1270. "u32".to_string()
  1271. }
  1272. fn generate_static(&self, dst: &mut String) {
  1273. write!(dst, "{}", self.to_bits()).unwrap();
  1274. }
  1275. fn generate_expr(container: &str) -> String {
  1276. format!("f32::from_bits({})", container)
  1277. }
  1278. }
  1279. macro_rules! plain_test_output {
  1280. ($($i:tt)*) => ($(
  1281. impl TestOutput for $i {
  1282. fn ty_name() -> String {
  1283. stringify!($i).to_string()
  1284. }
  1285. fn generate_static(&self, dst: &mut String) {
  1286. write!(dst, "{}", self).unwrap();
  1287. }
  1288. fn generate_expr(container: &str) -> String {
  1289. container.to_string()
  1290. }
  1291. }
  1292. )*)
  1293. }
  1294. plain_test_output!(i32 i64 i128 u32 u64 u128 bool);
  1295. impl<A, B> TestOutput for (A, B)
  1296. where
  1297. A: TestOutput,
  1298. B: TestOutput,
  1299. {
  1300. fn ty_name() -> String {
  1301. format!("({}, {})", A::ty_name(), B::ty_name())
  1302. }
  1303. fn generate_static(&self, dst: &mut String) {
  1304. dst.push_str("(");
  1305. self.0.generate_static(dst);
  1306. dst.push_str(", ");
  1307. self.1.generate_static(dst);
  1308. dst.push_str(")");
  1309. }
  1310. fn generate_expr(container: &str) -> String {
  1311. container.to_string()
  1312. }
  1313. }
  1314. trait FromFloat<T>: Sized {
  1315. fn cast(src: T) -> Option<Self>;
  1316. }
  1317. macro_rules! from_float {
  1318. ($($src:ident => $($dst:ident),+);+;) => {
  1319. $(
  1320. $(
  1321. impl FromFloat<$src> for $dst {
  1322. fn cast(src: $src) -> Option<$dst> {
  1323. use std::{$dst, $src};
  1324. if src.is_nan() ||
  1325. src.is_infinite() ||
  1326. src < std::$dst::MIN as $src ||
  1327. src > std::$dst::MAX as $src
  1328. {
  1329. None
  1330. } else {
  1331. Some(src as $dst)
  1332. }
  1333. }
  1334. }
  1335. )+
  1336. )+
  1337. }
  1338. }
  1339. from_float! {
  1340. f32 => i32, i64, i128, u32, u64, u128;
  1341. f64 => i32, i64, i128, u32, u64, u128;
  1342. }