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): (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): (MyU64, MyU32)| Some(a.0 << (b.0 % 64)),
  838. "builtins::int::shift::__ashldi3(a, b % 64)",
  839. );
  840. gen(
  841. |(a, b): (MyU128, MyU32)| Some(a.0 << (b.0 % 128)),
  842. "builtins::int::shift::__ashlti3(a, b % 128)",
  843. );
  844. gen(
  845. |(a, b): (MyI64, MyU32)| Some(a.0 >> (b.0 % 64)),
  846. "builtins::int::shift::__ashrdi3(a, b % 64)",
  847. );
  848. gen(
  849. |(a, b): (MyI128, MyU32)| Some(a.0 >> (b.0 % 128)),
  850. "builtins::int::shift::__ashrti3(a, b % 128)",
  851. );
  852. gen(
  853. |(a, b): (MyU64, MyU32)| Some(a.0 >> (b.0 % 64)),
  854. "builtins::int::shift::__lshrdi3(a, b % 64)",
  855. );
  856. gen(
  857. |(a, b): (MyU128, MyU32)| Some(a.0 >> (b.0 % 128)),
  858. "builtins::int::shift::__lshrti3(a, b % 128)",
  859. );
  860. // int/udiv.rs
  861. gen(
  862. |(a, b): (MyU64, MyU64)| {
  863. if b.0 == 0 {
  864. None
  865. } else {
  866. Some(a.0 / b.0)
  867. }
  868. },
  869. "builtins::int::udiv::__udivdi3(a, b)",
  870. );
  871. gen(
  872. |(a, b): (MyU64, MyU64)| {
  873. if b.0 == 0 {
  874. None
  875. } else {
  876. Some((a.0 / b.0, a.0 % b.0))
  877. }
  878. },
  879. "{
  880. let mut r = 0;
  881. (builtins::int::udiv::__udivmoddi4(a, b, Some(&mut r)), r)
  882. }",
  883. );
  884. gen(
  885. |(a, b): (MyU32, MyU32)| {
  886. if b.0 == 0 {
  887. None
  888. } else {
  889. Some((a.0 / b.0, a.0 % b.0))
  890. }
  891. },
  892. "{
  893. let mut r = 0;
  894. (builtins::int::udiv::__udivmodsi4(a, b, Some(&mut r)), r)
  895. }",
  896. );
  897. gen(
  898. |(a, b): (MyU32, MyU32)| {
  899. if b.0 == 0 {
  900. None
  901. } else {
  902. Some(a.0 / b.0)
  903. }
  904. },
  905. "builtins::int::udiv::__udivsi3(a, b)",
  906. );
  907. gen(
  908. |(a, b): (MyU32, MyU32)| {
  909. if b.0 == 0 {
  910. None
  911. } else {
  912. Some(a.0 % b.0)
  913. }
  914. },
  915. "builtins::int::udiv::__umodsi3(a, b)",
  916. );
  917. gen(
  918. |(a, b): (MyU64, MyU64)| {
  919. if b.0 == 0 {
  920. None
  921. } else {
  922. Some(a.0 % b.0)
  923. }
  924. },
  925. "builtins::int::udiv::__umoddi3(a, b)",
  926. );
  927. gen(
  928. |(a, b): (MyU128, MyU128)| {
  929. if b.0 == 0 {
  930. None
  931. } else {
  932. Some(a.0 / b.0)
  933. }
  934. },
  935. "builtins::int::udiv::__udivti3(a, b)",
  936. );
  937. gen(
  938. |(a, b): (MyU128, MyU128)| {
  939. if b.0 == 0 {
  940. None
  941. } else {
  942. Some(a.0 % b.0)
  943. }
  944. },
  945. "builtins::int::udiv::__umodti3(a, b)",
  946. );
  947. gen(
  948. |(a, b): (MyU128, MyU128)| {
  949. if b.0 == 0 {
  950. None
  951. } else {
  952. Some((a.0 / b.0, a.0 % b.0))
  953. }
  954. },
  955. "{
  956. let mut r = 0;
  957. (builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r)
  958. }",
  959. );
  960. }
  961. macro_rules! gen_float {
  962. ($name:ident,
  963. $fty:ident,
  964. $uty:ident,
  965. $bits:expr,
  966. $significand_bits:expr) => {
  967. pub fn $name<R>(rng: &mut R) -> $fty
  968. where
  969. R: Rng + ?Sized,
  970. {
  971. const BITS: u8 = $bits;
  972. const SIGNIFICAND_BITS: u8 = $significand_bits;
  973. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  974. const SIGN_MASK: $uty = (1 << (BITS - 1));
  975. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  976. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  977. unsafe {
  978. mem::transmute(
  979. ((sign as $uty) << (BITS - 1))
  980. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  981. | (significand & SIGNIFICAND_MASK),
  982. )
  983. }
  984. }
  985. if rng.gen_range(0, 10) == 1 {
  986. // Special values
  987. *[
  988. -0.0,
  989. 0.0,
  990. ::std::$fty::MIN,
  991. ::std::$fty::MIN_POSITIVE,
  992. ::std::$fty::MAX,
  993. ::std::$fty::NAN,
  994. ::std::$fty::INFINITY,
  995. -::std::$fty::INFINITY,
  996. ]
  997. .choose(rng)
  998. .unwrap()
  999. } else if rng.gen_range(0, 10) == 1 {
  1000. // NaN patterns
  1001. mk_f32(rng.gen(), rng.gen(), 0)
  1002. } else if rng.gen() {
  1003. // Denormalized
  1004. mk_f32(rng.gen(), 0, rng.gen())
  1005. } else {
  1006. // Random anything
  1007. mk_f32(rng.gen(), rng.gen(), rng.gen())
  1008. }
  1009. }
  1010. };
  1011. }
  1012. gen_float!(gen_f32, f32, u32, 32, 23);
  1013. gen_float!(gen_f64, f64, u64, 64, 52);
  1014. macro_rules! gen_large_float {
  1015. ($name:ident,
  1016. $fty:ident,
  1017. $uty:ident,
  1018. $bits:expr,
  1019. $significand_bits:expr) => {
  1020. pub fn $name<R>(rng: &mut R) -> $fty
  1021. where
  1022. R: Rng + ?Sized,
  1023. {
  1024. const BITS: u8 = $bits;
  1025. const SIGNIFICAND_BITS: u8 = $significand_bits;
  1026. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  1027. const SIGN_MASK: $uty = (1 << (BITS - 1));
  1028. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  1029. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  1030. unsafe {
  1031. mem::transmute(
  1032. ((sign as $uty) << (BITS - 1))
  1033. | ((exponent & EXPONENT_MASK) << SIGNIFICAND_BITS)
  1034. | (significand & SIGNIFICAND_MASK),
  1035. )
  1036. }
  1037. }
  1038. if rng.gen_range(0, 10) == 1 {
  1039. // Special values
  1040. *[
  1041. -0.0,
  1042. 0.0,
  1043. ::std::$fty::MIN,
  1044. ::std::$fty::MIN_POSITIVE,
  1045. ::std::$fty::MAX,
  1046. ::std::$fty::NAN,
  1047. ::std::$fty::INFINITY,
  1048. -::std::$fty::INFINITY,
  1049. ]
  1050. .choose(rng)
  1051. .unwrap()
  1052. } else if rng.gen_range(0, 10) == 1 {
  1053. // NaN patterns
  1054. mk_f32(rng.gen(), rng.gen(), 0)
  1055. } else if rng.gen() {
  1056. // Denormalized
  1057. mk_f32(rng.gen(), 0, rng.gen())
  1058. } else {
  1059. // Random anything
  1060. rng.gen::<$fty>()
  1061. }
  1062. }
  1063. };
  1064. }
  1065. gen_large_float!(gen_large_f32, f32, u32, 32, 23);
  1066. gen_large_float!(gen_large_f64, f64, u64, 64, 52);
  1067. trait TestInput: Hash + Eq + fmt::Debug {
  1068. fn ty_name() -> String;
  1069. fn generate_lets(container: &str, cnt: &mut u8) -> String;
  1070. fn generate_static(&self, dst: &mut String);
  1071. }
  1072. trait TestOutput {
  1073. fn ty_name() -> String;
  1074. fn generate_static(&self, dst: &mut String);
  1075. fn generate_expr(container: &str) -> String;
  1076. }
  1077. fn gen<F, A, R>(mut generate: F, test: &str)
  1078. where
  1079. F: FnMut(A) -> Option<R>,
  1080. A: TestInput + Copy,
  1081. R: TestOutput,
  1082. rand::distributions::Standard: rand::distributions::Distribution<A>,
  1083. {
  1084. let rng = &mut rand::thread_rng();
  1085. let testname = test.split("::").last().unwrap().split("(").next().unwrap();
  1086. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  1087. let out_file = out_dir.join("generated.rs");
  1088. let mut testcases = HashMap::new();
  1089. let mut n = NTESTS;
  1090. while n > 0 {
  1091. let input: A = rng.gen();
  1092. if testcases.contains_key(&input) {
  1093. continue;
  1094. }
  1095. let output = match generate(input) {
  1096. Some(o) => o,
  1097. None => continue,
  1098. };
  1099. testcases.insert(input, output);
  1100. n -= 1;
  1101. }
  1102. let mut contents = String::new();
  1103. contents.push_str(&format!("mod {} {{\nuse super::*;\n", testname));
  1104. contents.push_str("#[test]\n");
  1105. contents.push_str("fn test() {\n");
  1106. contents.push_str(&format!(
  1107. "static TESTS: [({}, {}); {}] = [\n",
  1108. A::ty_name(),
  1109. R::ty_name(),
  1110. NTESTS
  1111. ));
  1112. for (input, output) in testcases {
  1113. contents.push_str(" (");
  1114. input.generate_static(&mut contents);
  1115. contents.push_str(", ");
  1116. output.generate_static(&mut contents);
  1117. contents.push_str("),\n");
  1118. }
  1119. contents.push_str("];\n");
  1120. contents.push_str(&format!(
  1121. r#"
  1122. for &(inputs, output) in TESTS.iter() {{
  1123. {}
  1124. assert_eq!({}, {}, "inputs {{:?}}", inputs)
  1125. }}
  1126. "#,
  1127. A::generate_lets("inputs", &mut 0),
  1128. R::generate_expr("output"),
  1129. test,
  1130. ));
  1131. contents.push_str("\n}\n");
  1132. contents.push_str("\n}\n");
  1133. OpenOptions::new()
  1134. .write(true)
  1135. .append(true)
  1136. .create(true)
  1137. .open(out_file)
  1138. .unwrap()
  1139. .write_all(contents.as_bytes())
  1140. .unwrap();
  1141. }
  1142. macro_rules! my_float {
  1143. ($(struct $name:ident($inner:ident) = $gen:ident;)*) => ($(
  1144. #[derive(Debug, Clone, Copy)]
  1145. struct $name($inner);
  1146. impl TestInput for $name {
  1147. fn ty_name() -> String {
  1148. format!("u{}", &stringify!($inner)[1..])
  1149. }
  1150. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1151. let me = *cnt;
  1152. *cnt += 1;
  1153. format!("let {} = {}::from_bits({});\n",
  1154. (b'a' + me) as char,
  1155. stringify!($inner),
  1156. container)
  1157. }
  1158. fn generate_static(&self, dst: &mut String) {
  1159. write!(dst, "{}", self.0.to_bits()).unwrap();
  1160. }
  1161. }
  1162. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1163. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1164. $name($gen(r))
  1165. }
  1166. }
  1167. impl Hash for $name {
  1168. fn hash<H: Hasher>(&self, h: &mut H) {
  1169. self.0.to_bits().hash(h)
  1170. }
  1171. }
  1172. impl PartialEq for $name {
  1173. fn eq(&self, other: &$name) -> bool {
  1174. self.0.to_bits() == other.0.to_bits()
  1175. }
  1176. }
  1177. impl Eq for $name {}
  1178. )*)
  1179. }
  1180. my_float! {
  1181. struct MyF64(f64) = gen_f64;
  1182. struct LargeF64(f64) = gen_large_f64;
  1183. struct MyF32(f32) = gen_f32;
  1184. struct LargeF32(f32) = gen_large_f32;
  1185. }
  1186. macro_rules! my_integer {
  1187. ($(struct $name:ident($inner:ident);)*) => ($(
  1188. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
  1189. struct $name($inner);
  1190. impl TestInput for $name {
  1191. fn ty_name() -> String {
  1192. stringify!($inner).to_string()
  1193. }
  1194. fn generate_lets(container: &str, cnt: &mut u8) -> String {
  1195. let me = *cnt;
  1196. *cnt += 1;
  1197. format!("let {} = {};\n",
  1198. (b'a' + me) as char,
  1199. container)
  1200. }
  1201. fn generate_static(&self, dst: &mut String) {
  1202. write!(dst, "{}", self.0).unwrap();
  1203. }
  1204. }
  1205. impl rand::distributions::Distribution<$name> for rand::distributions::Standard {
  1206. fn sample<R: rand::Rng + ?Sized >(&self, r: &mut R) -> $name {
  1207. let bits = (0 as $inner).count_zeros();
  1208. let mut mk = || {
  1209. if r.gen_range(0, 10) == 1 {
  1210. *[
  1211. ::std::$inner::MAX >> (bits / 2),
  1212. 0,
  1213. ::std::$inner::MIN >> (bits / 2),
  1214. ].choose(r).unwrap()
  1215. } else {
  1216. r.gen::<$inner>()
  1217. }
  1218. };
  1219. let a = mk();
  1220. let b = mk();
  1221. $name((a << (bits / 2)) | (b & (!0 << (bits / 2))))
  1222. }
  1223. }
  1224. )*)
  1225. }
  1226. my_integer! {
  1227. struct MyI32(i32);
  1228. struct MyI64(i64);
  1229. struct MyI128(i128);
  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. }