build.rs 88 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864
  1. #![feature(i128_type)]
  2. use std::env;
  3. fn main() {
  4. println!("cargo:rerun-if-changed=build.rs");
  5. let target = env::var("TARGET").unwrap();
  6. // Emscripten's runtime includes all the builtins
  7. if target.contains("emscripten") {
  8. return;
  9. }
  10. // NOTE we are going to assume that llvm-target, what determines our codegen option, matches the
  11. // target triple. This is usually correct for our built-in targets but can break in presence of
  12. // custom targets, which can have arbitrary names.
  13. let llvm_target = target.split('-').collect::<Vec<_>>();
  14. // Build test files
  15. tests::generate();
  16. // Build missing intrinsics from compiler-rt C source code
  17. #[cfg(feature = "c")]
  18. c::compile(&llvm_target);
  19. // To compile intrinsics.rs for thumb targets, where there is no libc
  20. if llvm_target[0].starts_with("thumb") {
  21. println!("cargo:rustc-cfg=thumb")
  22. }
  23. // compiler-rt `cfg`s away some intrinsics for thumbv6m because that target doesn't have full
  24. // THUMBv2 support. We have to cfg our code accordingly.
  25. if llvm_target[0] == "thumbv6m" {
  26. println!("cargo:rustc-cfg=thumbv6m")
  27. }
  28. }
  29. mod tests {
  30. extern crate cast;
  31. extern crate rand;
  32. use std::collections::HashSet;
  33. use std::fmt::Write;
  34. use std::fs::File;
  35. use std::hash::Hash;
  36. use std::path::PathBuf;
  37. use std::{env, mem};
  38. use self::cast::{f32, f64, u32, u64, i32, i64};
  39. use self::rand::Rng;
  40. const NTESTS: usize = 10_000;
  41. macro_rules! test {
  42. ($($intrinsic:ident,)+) => {
  43. $(
  44. mk_file::<$intrinsic>();
  45. )+
  46. }
  47. }
  48. pub fn generate() {
  49. // TODO move to main
  50. test! {
  51. // float/add.rs
  52. Adddf3,
  53. Addsf3,
  54. // float/conv.rs
  55. Fixdfdi,
  56. Fixdfsi,
  57. Fixsfdi,
  58. Fixsfsi,
  59. Fixunsdfdi,
  60. Fixunsdfsi,
  61. Fixunssfdi,
  62. Fixunssfsi,
  63. Floatdidf,
  64. Floatsidf,
  65. Floatsisf,
  66. Floatundidf,
  67. Floatunsidf,
  68. Floatunsisf,
  69. // float/pow.rs
  70. Powidf2,
  71. Powisf2,
  72. // float/sub.rs
  73. Subdf3,
  74. Subsf3,
  75. // int/mul.rs
  76. Muldi3,
  77. Mulodi4,
  78. Mulosi4,
  79. Muloti4,
  80. Multi3,
  81. // int/sdiv.rs
  82. Divdi3,
  83. Divmoddi4,
  84. Divmodsi4,
  85. Divsi3,
  86. Divti3,
  87. Moddi3,
  88. Modsi3,
  89. Modti3,
  90. // int/shift.rs
  91. Ashldi3,
  92. Ashlti3,
  93. Ashrdi3,
  94. Ashrti3,
  95. Lshrdi3,
  96. Lshrti3,
  97. // int/udiv.rs
  98. Udivdi3,
  99. Udivmoddi4,
  100. Udivmodsi4,
  101. Udivmodti4,
  102. Udivsi3,
  103. Udivti3,
  104. Umoddi3,
  105. Umodsi3,
  106. Umodti3,
  107. }
  108. }
  109. #[derive(Eq, Hash, PartialEq)]
  110. pub struct Adddf3 {
  111. a: u64, // f64
  112. b: u64, // f64
  113. c: u64, // f64
  114. }
  115. impl TestCase for Adddf3 {
  116. fn name() -> &'static str {
  117. "adddf3"
  118. }
  119. fn generate<R>(rng: &mut R) -> Option<Self>
  120. where
  121. R: Rng,
  122. Self: Sized,
  123. {
  124. let a = gen_f64(rng);
  125. let b = gen_f64(rng);
  126. let c = a + b;
  127. // TODO accept NaNs. We don't do that right now because we can't check
  128. // for NaN-ness on the thumb targets (due to missing intrinsics)
  129. if a.is_nan() || b.is_nan() || c.is_nan() {
  130. return None;
  131. }
  132. Some(
  133. Adddf3 {
  134. a: to_u64(a),
  135. b: to_u64(b),
  136. c: to_u64(c),
  137. },
  138. )
  139. }
  140. fn to_string(&self, buffer: &mut String) {
  141. writeln!(
  142. buffer,
  143. "(({a}, {b}), {c}),",
  144. a = self.a,
  145. b = self.b,
  146. c = self.c
  147. )
  148. .unwrap();
  149. }
  150. fn prologue() -> &'static str {
  151. r#"
  152. #[cfg(all(target_arch = "arm",
  153. not(any(target_env = "gnu", target_env = "musl")),
  154. target_os = "linux",
  155. test))]
  156. use core::mem;
  157. #[cfg(not(all(target_arch = "arm",
  158. not(any(target_env = "gnu", target_env = "musl")),
  159. target_os = "linux",
  160. test)))]
  161. use std::mem;
  162. use compiler_builtins::float::add::__adddf3;
  163. fn mk_f64(x: u64) -> f64 {
  164. unsafe { mem::transmute(x) }
  165. }
  166. fn to_u64(x: f64) -> u64 {
  167. unsafe { mem::transmute(x) }
  168. }
  169. static TEST_CASES: &[((u64, u64), u64)] = &[
  170. "#
  171. }
  172. fn epilogue() -> &'static str {
  173. "
  174. ];
  175. #[test]
  176. fn adddf3() {
  177. for &((a, b), c) in TEST_CASES {
  178. let c_ = __adddf3(mk_f64(a), mk_f64(b));
  179. assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
  180. }
  181. }
  182. "
  183. }
  184. }
  185. #[derive(Eq, Hash, PartialEq)]
  186. pub struct Addsf3 {
  187. a: u32, // f32
  188. b: u32, // f32
  189. c: u32, // f32
  190. }
  191. impl TestCase for Addsf3 {
  192. fn name() -> &'static str {
  193. "addsf3"
  194. }
  195. fn generate<R>(rng: &mut R) -> Option<Self>
  196. where
  197. R: Rng,
  198. Self: Sized,
  199. {
  200. let a = gen_f32(rng);
  201. let b = gen_f32(rng);
  202. let c = a + b;
  203. // TODO accept NaNs. We don't do that right now because we can't check
  204. // for NaN-ness on the thumb targets (due to missing intrinsics)
  205. if a.is_nan() || b.is_nan() || c.is_nan() {
  206. return None;
  207. }
  208. Some(
  209. Addsf3 {
  210. a: to_u32(a),
  211. b: to_u32(b),
  212. c: to_u32(c),
  213. },
  214. )
  215. }
  216. fn to_string(&self, buffer: &mut String) {
  217. writeln!(
  218. buffer,
  219. "(({a}, {b}), {c}),",
  220. a = self.a,
  221. b = self.b,
  222. c = self.c
  223. )
  224. .unwrap();
  225. }
  226. fn prologue() -> &'static str {
  227. r#"
  228. #[cfg(all(target_arch = "arm",
  229. not(any(target_env = "gnu", target_env = "musl")),
  230. target_os = "linux",
  231. test))]
  232. use core::mem;
  233. #[cfg(not(all(target_arch = "arm",
  234. not(any(target_env = "gnu", target_env = "musl")),
  235. target_os = "linux",
  236. test)))]
  237. use std::mem;
  238. use compiler_builtins::float::add::__addsf3;
  239. fn mk_f32(x: u32) -> f32 {
  240. unsafe { mem::transmute(x) }
  241. }
  242. fn to_u32(x: f32) -> u32 {
  243. unsafe { mem::transmute(x) }
  244. }
  245. static TEST_CASES: &[((u32, u32), u32)] = &[
  246. "#
  247. }
  248. fn epilogue() -> &'static str {
  249. "
  250. ];
  251. #[test]
  252. fn addsf3() {
  253. for &((a, b), c) in TEST_CASES {
  254. let c_ = __addsf3(mk_f32(a), mk_f32(b));
  255. assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
  256. }
  257. }
  258. "
  259. }
  260. }
  261. #[derive(Eq, Hash, PartialEq)]
  262. pub struct Ashldi3 {
  263. a: u64,
  264. b: u32,
  265. c: u64,
  266. }
  267. impl TestCase for Ashldi3 {
  268. fn name() -> &'static str {
  269. "ashldi3"
  270. }
  271. fn generate<R>(rng: &mut R) -> Option<Self>
  272. where
  273. R: Rng,
  274. Self: Sized,
  275. {
  276. let a = gen_u64(rng);
  277. let b = (rng.gen::<u8>() % 64) as u32;
  278. let c = a << b;
  279. Some(Ashldi3 { a, b, c })
  280. }
  281. fn to_string(&self, buffer: &mut String) {
  282. writeln!(
  283. buffer,
  284. "(({a}, {b}), {c}),",
  285. a = self.a,
  286. b = self.b,
  287. c = self.c
  288. )
  289. .unwrap();
  290. }
  291. fn prologue() -> &'static str {
  292. "
  293. use compiler_builtins::int::shift::__ashldi3;
  294. static TEST_CASES: &[((u64, u32), u64)] = &[
  295. "
  296. }
  297. fn epilogue() -> &'static str {
  298. "
  299. ];
  300. #[test]
  301. fn ashldi3() {
  302. for &((a, b), c) in TEST_CASES {
  303. let c_ = __ashldi3(a, b);
  304. assert_eq!(((a, b), c), ((a, b), c_));
  305. }
  306. }
  307. "
  308. }
  309. }
  310. #[derive(Eq, Hash, PartialEq)]
  311. pub struct Ashlti3 {
  312. a: u128,
  313. b: u32,
  314. c: u128,
  315. }
  316. impl TestCase for Ashlti3 {
  317. fn name() -> &'static str {
  318. "ashlti3"
  319. }
  320. fn generate<R>(rng: &mut R) -> Option<Self>
  321. where
  322. R: Rng,
  323. Self: Sized,
  324. {
  325. let a = gen_u128(rng);
  326. let b = (rng.gen::<u8>() % 128) as u32;
  327. let c = a << b;
  328. Some(Ashlti3 { a, b, c })
  329. }
  330. fn to_string(&self, buffer: &mut String) {
  331. writeln!(
  332. buffer,
  333. "(({a}, {b}), {c}),",
  334. a = self.a,
  335. b = self.b,
  336. c = self.c
  337. )
  338. .unwrap();
  339. }
  340. fn prologue() -> &'static str {
  341. "
  342. use compiler_builtins::int::shift::__ashlti3;
  343. static TEST_CASES: &[((u128, u32), u128)] = &[
  344. "
  345. }
  346. fn epilogue() -> &'static str {
  347. "
  348. ];
  349. #[test]
  350. fn ashlti3() {
  351. for &((a, b), c) in TEST_CASES {
  352. let c_ = __ashlti3(a, b);
  353. assert_eq!(((a, b), c), ((a, b), c_));
  354. }
  355. }
  356. "
  357. }
  358. }
  359. #[derive(Eq, Hash, PartialEq)]
  360. pub struct Ashrdi3 {
  361. a: i64,
  362. b: u32,
  363. c: i64,
  364. }
  365. impl TestCase for Ashrdi3 {
  366. fn name() -> &'static str {
  367. "ashrdi3"
  368. }
  369. fn generate<R>(rng: &mut R) -> Option<Self>
  370. where
  371. R: Rng,
  372. Self: Sized,
  373. {
  374. let a = gen_i64(rng);
  375. let b = (rng.gen::<u8>() % 64) as u32;
  376. let c = a >> b;
  377. Some(Ashrdi3 { a, b, c })
  378. }
  379. fn to_string(&self, buffer: &mut String) {
  380. writeln!(
  381. buffer,
  382. "(({a}, {b}), {c}),",
  383. a = self.a,
  384. b = self.b,
  385. c = self.c
  386. )
  387. .unwrap();
  388. }
  389. fn prologue() -> &'static str {
  390. "
  391. use compiler_builtins::int::shift::__ashrdi3;
  392. static TEST_CASES: &[((i64, u32), i64)] = &[
  393. "
  394. }
  395. fn epilogue() -> &'static str {
  396. "
  397. ];
  398. #[test]
  399. fn ashrdi3() {
  400. for &((a, b), c) in TEST_CASES {
  401. let c_ = __ashrdi3(a, b);
  402. assert_eq!(((a, b), c), ((a, b), c_));
  403. }
  404. }
  405. "
  406. }
  407. }
  408. #[derive(Eq, Hash, PartialEq)]
  409. pub struct Ashrti3 {
  410. a: i128,
  411. b: u32,
  412. c: i128,
  413. }
  414. impl TestCase for Ashrti3 {
  415. fn name() -> &'static str {
  416. "ashrti3"
  417. }
  418. fn generate<R>(rng: &mut R) -> Option<Self>
  419. where
  420. R: Rng,
  421. Self: Sized,
  422. {
  423. let a = gen_i128(rng);
  424. let b = (rng.gen::<u8>() % 128) as u32;
  425. let c = a >> b;
  426. Some(Ashrti3 { a, b, c })
  427. }
  428. fn to_string(&self, buffer: &mut String) {
  429. writeln!(
  430. buffer,
  431. "(({a}, {b}), {c}),",
  432. a = self.a,
  433. b = self.b,
  434. c = self.c
  435. )
  436. .unwrap();
  437. }
  438. fn prologue() -> &'static str {
  439. "
  440. use compiler_builtins::int::shift::__ashrti3;
  441. static TEST_CASES: &[((i128, u32), i128)] = &[
  442. "
  443. }
  444. fn epilogue() -> &'static str {
  445. "
  446. ];
  447. #[test]
  448. fn ashrti3() {
  449. for &((a, b), c) in TEST_CASES {
  450. let c_ = __ashrti3(a, b);
  451. assert_eq!(((a, b), c), ((a, b), c_));
  452. }
  453. }
  454. "
  455. }
  456. }
  457. #[derive(Eq, Hash, PartialEq)]
  458. pub struct Divmoddi4 {
  459. a: i64,
  460. b: i64,
  461. c: i64,
  462. rem: i64,
  463. }
  464. impl TestCase for Divmoddi4 {
  465. fn name() -> &'static str {
  466. "divmoddi4"
  467. }
  468. fn generate<R>(rng: &mut R) -> Option<Self>
  469. where
  470. R: Rng,
  471. Self: Sized,
  472. {
  473. let a = gen_i64(rng);
  474. let b = gen_i64(rng);
  475. if b == 0 {
  476. return None;
  477. }
  478. let c = a / b;
  479. let rem = a % b;
  480. Some(Divmoddi4 { a, b, c, rem })
  481. }
  482. fn to_string(&self, buffer: &mut String) {
  483. writeln!(
  484. buffer,
  485. "(({a}, {b}), ({c}, {rem})),",
  486. a = self.a,
  487. b = self.b,
  488. c = self.c,
  489. rem = self.rem
  490. )
  491. .unwrap();
  492. }
  493. fn prologue() -> &'static str {
  494. "
  495. use compiler_builtins::int::sdiv::__divmoddi4;
  496. static TEST_CASES: &[((i64, i64), (i64, i64))] = &[
  497. "
  498. }
  499. fn epilogue() -> &'static str {
  500. "
  501. ];
  502. #[test]
  503. fn divmoddi4() {
  504. for &((a, b), (c, rem)) in TEST_CASES {
  505. let mut rem_ = 0;
  506. let c_ = __divmoddi4(a, b, &mut rem_);
  507. assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
  508. }
  509. }
  510. "
  511. }
  512. }
  513. #[derive(Eq, Hash, PartialEq)]
  514. pub struct Divdi3 {
  515. a: i64,
  516. b: i64,
  517. c: i64,
  518. }
  519. impl TestCase for Divdi3 {
  520. fn name() -> &'static str {
  521. "divdi3"
  522. }
  523. fn generate<R>(rng: &mut R) -> Option<Self>
  524. where
  525. R: Rng,
  526. Self: Sized,
  527. {
  528. let a = gen_i64(rng);
  529. let b = gen_i64(rng);
  530. if b == 0 {
  531. return None;
  532. }
  533. let c = a / b;
  534. Some(Divdi3 { a, b, c })
  535. }
  536. fn to_string(&self, buffer: &mut String) {
  537. writeln!(
  538. buffer,
  539. "(({a}, {b}), {c}),",
  540. a = self.a,
  541. b = self.b,
  542. c = self.c
  543. )
  544. .unwrap();
  545. }
  546. fn prologue() -> &'static str {
  547. "
  548. use compiler_builtins::int::sdiv::__divdi3;
  549. static TEST_CASES: &[((i64, i64), i64)] = &[
  550. "
  551. }
  552. fn epilogue() -> &'static str {
  553. "
  554. ];
  555. #[test]
  556. fn divdi3() {
  557. for &((a, b), c) in TEST_CASES {
  558. let c_ = __divdi3(a, b);
  559. assert_eq!(((a, b), c), ((a, b), c_));
  560. }
  561. }
  562. "
  563. }
  564. }
  565. #[derive(Eq, Hash, PartialEq)]
  566. pub struct Divmodsi4 {
  567. a: i32,
  568. b: i32,
  569. c: i32,
  570. rem: i32,
  571. }
  572. impl TestCase for Divmodsi4 {
  573. fn name() -> &'static str {
  574. "divmodsi4"
  575. }
  576. fn generate<R>(rng: &mut R) -> Option<Self>
  577. where
  578. R: Rng,
  579. Self: Sized,
  580. {
  581. let a = gen_i32(rng);
  582. let b = gen_i32(rng);
  583. if b == 0 {
  584. return None;
  585. }
  586. let c = a / b;
  587. let rem = a % b;
  588. Some(Divmodsi4 { a, b, c, rem })
  589. }
  590. fn to_string(&self, buffer: &mut String) {
  591. writeln!(
  592. buffer,
  593. "(({a}, {b}), ({c}, {rem})),",
  594. a = self.a,
  595. b = self.b,
  596. c = self.c,
  597. rem = self.rem
  598. )
  599. .unwrap();
  600. }
  601. fn prologue() -> &'static str {
  602. "
  603. use compiler_builtins::int::sdiv::__divmodsi4;
  604. static TEST_CASES: &[((i32, i32), (i32, i32))] = &[
  605. "
  606. }
  607. fn epilogue() -> &'static str {
  608. "
  609. ];
  610. #[test]
  611. fn divmodsi4() {
  612. for &((a, b), (c, rem)) in TEST_CASES {
  613. let mut rem_ = 0;
  614. let c_ = __divmodsi4(a, b, &mut rem_);
  615. assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
  616. }
  617. }
  618. "
  619. }
  620. }
  621. #[derive(Eq, Hash, PartialEq)]
  622. pub struct Divsi3 {
  623. a: i32,
  624. b: i32,
  625. c: i32,
  626. }
  627. impl TestCase for Divsi3 {
  628. fn name() -> &'static str {
  629. "divsi3"
  630. }
  631. fn generate<R>(rng: &mut R) -> Option<Self>
  632. where
  633. R: Rng,
  634. Self: Sized,
  635. {
  636. let a = gen_i32(rng);
  637. let b = gen_i32(rng);
  638. if b == 0 {
  639. return None;
  640. }
  641. let c = a / b;
  642. Some(Divsi3 { a, b, c })
  643. }
  644. fn to_string(&self, buffer: &mut String) {
  645. writeln!(
  646. buffer,
  647. "(({a}, {b}), {c}),",
  648. a = self.a,
  649. b = self.b,
  650. c = self.c
  651. )
  652. .unwrap();
  653. }
  654. fn prologue() -> &'static str {
  655. "
  656. use compiler_builtins::int::sdiv::__divsi3;
  657. static TEST_CASES: &[((i32, i32), i32)] = &[
  658. "
  659. }
  660. fn epilogue() -> &'static str {
  661. "
  662. ];
  663. #[test]
  664. fn divsi3() {
  665. for &((a, b), c) in TEST_CASES {
  666. let c_ = __divsi3(a, b);
  667. assert_eq!(((a, b), c), ((a, b), c_));
  668. }
  669. }
  670. "
  671. }
  672. }
  673. #[derive(Eq, Hash, PartialEq)]
  674. pub struct Divti3 {
  675. a: i128,
  676. b: i128,
  677. c: i128,
  678. }
  679. impl TestCase for Divti3 {
  680. fn name() -> &'static str {
  681. "divti3"
  682. }
  683. fn generate<R>(rng: &mut R) -> Option<Self>
  684. where
  685. R: Rng,
  686. Self: Sized,
  687. {
  688. let a = gen_i128(rng);
  689. let b = gen_i128(rng);
  690. if b == 0 {
  691. return None;
  692. }
  693. let c = a / b;
  694. Some(Divti3 { a, b, c })
  695. }
  696. fn to_string(&self, buffer: &mut String) {
  697. writeln!(
  698. buffer,
  699. "(({a}, {b}), {c}),",
  700. a = self.a,
  701. b = self.b,
  702. c = self.c
  703. )
  704. .unwrap();
  705. }
  706. fn prologue() -> &'static str {
  707. "
  708. use compiler_builtins::int::sdiv::__divti3;
  709. static TEST_CASES: &[((i128, i128), i128)] = &[
  710. "
  711. }
  712. fn epilogue() -> &'static str {
  713. "
  714. ];
  715. #[test]
  716. fn divti3() {
  717. for &((a, b), c) in TEST_CASES {
  718. let c_ = __divti3(a, b);
  719. assert_eq!(((a, b), c), ((a, b), c_));
  720. }
  721. }
  722. "
  723. }
  724. }
  725. #[derive(Eq, Hash, PartialEq)]
  726. pub struct Fixdfdi {
  727. a: u64, // f64
  728. b: i64,
  729. }
  730. impl TestCase for Fixdfdi {
  731. fn name() -> &'static str {
  732. "fixdfdi"
  733. }
  734. fn generate<R>(rng: &mut R) -> Option<Self>
  735. where
  736. R: Rng,
  737. Self: Sized,
  738. {
  739. let a = gen_f64(rng);
  740. i64(a).ok().map(|b| Fixdfdi { a: to_u64(a), b })
  741. }
  742. fn to_string(&self, buffer: &mut String) {
  743. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  744. }
  745. fn prologue() -> &'static str {
  746. r#"
  747. #[cfg(all(target_arch = "arm",
  748. not(any(target_env = "gnu", target_env = "musl")),
  749. target_os = "linux",
  750. test))]
  751. use core::mem;
  752. #[cfg(not(all(target_arch = "arm",
  753. not(any(target_env = "gnu", target_env = "musl")),
  754. target_os = "linux",
  755. test)))]
  756. use std::mem;
  757. use compiler_builtins::float::conv::__fixdfdi;
  758. fn mk_f64(x: u64) -> f64 {
  759. unsafe { mem::transmute(x) }
  760. }
  761. static TEST_CASES: &[((u64,), i64)] = &[
  762. "#
  763. }
  764. fn epilogue() -> &'static str {
  765. "
  766. ];
  767. #[test]
  768. fn fixdfdi() {
  769. for &((a,), b) in TEST_CASES {
  770. let b_ = __fixdfdi(mk_f64(a));
  771. assert_eq!(((a,), b), ((a,), b_));
  772. }
  773. }
  774. "
  775. }
  776. }
  777. #[derive(Eq, Hash, PartialEq)]
  778. pub struct Fixdfsi {
  779. a: u64, // f64
  780. b: i32,
  781. }
  782. impl TestCase for Fixdfsi {
  783. fn name() -> &'static str {
  784. "fixdfsi"
  785. }
  786. fn generate<R>(rng: &mut R) -> Option<Self>
  787. where
  788. R: Rng,
  789. Self: Sized,
  790. {
  791. let a = gen_f64(rng);
  792. i32(a).ok().map(|b| Fixdfsi { a: to_u64(a), b })
  793. }
  794. fn to_string(&self, buffer: &mut String) {
  795. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  796. }
  797. fn prologue() -> &'static str {
  798. r#"
  799. #[cfg(all(target_arch = "arm",
  800. not(any(target_env = "gnu", target_env = "musl")),
  801. target_os = "linux",
  802. test))]
  803. use core::mem;
  804. #[cfg(not(all(target_arch = "arm",
  805. not(any(target_env = "gnu", target_env = "musl")),
  806. target_os = "linux",
  807. test)))]
  808. use std::mem;
  809. use compiler_builtins::float::conv::__fixdfsi;
  810. fn mk_f64(x: u64) -> f64 {
  811. unsafe { mem::transmute(x) }
  812. }
  813. static TEST_CASES: &[((u64,), i32)] = &[
  814. "#
  815. }
  816. fn epilogue() -> &'static str {
  817. "
  818. ];
  819. #[test]
  820. fn fixdfdi() {
  821. for &((a,), b) in TEST_CASES {
  822. let b_ = __fixdfsi(mk_f64(a));
  823. assert_eq!(((a,), b), ((a,), b_));
  824. }
  825. }
  826. "
  827. }
  828. }
  829. #[derive(Eq, Hash, PartialEq)]
  830. pub struct Fixsfdi {
  831. a: u32, // f32
  832. b: i64,
  833. }
  834. impl TestCase for Fixsfdi {
  835. fn name() -> &'static str {
  836. "fixsfdi"
  837. }
  838. fn generate<R>(rng: &mut R) -> Option<Self>
  839. where
  840. R: Rng,
  841. Self: Sized,
  842. {
  843. let a = gen_f32(rng);
  844. i64(a).ok().map(|b| Fixsfdi { a: to_u32(a), b })
  845. }
  846. fn to_string(&self, buffer: &mut String) {
  847. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  848. }
  849. fn prologue() -> &'static str {
  850. r#"
  851. #[cfg(all(target_arch = "arm",
  852. not(any(target_env = "gnu", target_env = "musl")),
  853. target_os = "linux",
  854. test))]
  855. use core::mem;
  856. #[cfg(not(all(target_arch = "arm",
  857. not(any(target_env = "gnu", target_env = "musl")),
  858. target_os = "linux",
  859. test)))]
  860. use std::mem;
  861. use compiler_builtins::float::conv::__fixsfdi;
  862. fn mk_f32(x: u32) -> f32 {
  863. unsafe { mem::transmute(x) }
  864. }
  865. static TEST_CASES: &[((u32,), i64)] = &[
  866. "#
  867. }
  868. fn epilogue() -> &'static str {
  869. "
  870. ];
  871. #[test]
  872. fn fixsfdi() {
  873. for &((a,), b) in TEST_CASES {
  874. let b_ = __fixsfdi(mk_f32(a));
  875. assert_eq!(((a,), b), ((a,), b_));
  876. }
  877. }
  878. "
  879. }
  880. }
  881. #[derive(Eq, Hash, PartialEq)]
  882. pub struct Fixsfsi {
  883. a: u32, // f32
  884. b: i32,
  885. }
  886. impl TestCase for Fixsfsi {
  887. fn name() -> &'static str {
  888. "fixsfsi"
  889. }
  890. fn generate<R>(rng: &mut R) -> Option<Self>
  891. where
  892. R: Rng,
  893. Self: Sized,
  894. {
  895. let a = gen_f32(rng);
  896. i32(a).ok().map(|b| Fixsfsi { a: to_u32(a), b })
  897. }
  898. fn to_string(&self, buffer: &mut String) {
  899. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  900. }
  901. fn prologue() -> &'static str {
  902. r#"
  903. #[cfg(all(target_arch = "arm",
  904. not(any(target_env = "gnu", target_env = "musl")),
  905. target_os = "linux",
  906. test))]
  907. use core::mem;
  908. #[cfg(not(all(target_arch = "arm",
  909. not(any(target_env = "gnu", target_env = "musl")),
  910. target_os = "linux",
  911. test)))]
  912. use std::mem;
  913. use compiler_builtins::float::conv::__fixsfsi;
  914. fn mk_f32(x: u32) -> f32 {
  915. unsafe { mem::transmute(x) }
  916. }
  917. static TEST_CASES: &[((u32,), i32)] = &[
  918. "#
  919. }
  920. fn epilogue() -> &'static str {
  921. "
  922. ];
  923. #[test]
  924. fn fixsfdi() {
  925. for &((a,), b) in TEST_CASES {
  926. let b_ = __fixsfsi(mk_f32(a));
  927. assert_eq!(((a,), b), ((a,), b_));
  928. }
  929. }
  930. "
  931. }
  932. }
  933. #[derive(Eq, Hash, PartialEq)]
  934. pub struct Fixunsdfdi {
  935. a: u64, // f64
  936. b: u64,
  937. }
  938. impl TestCase for Fixunsdfdi {
  939. fn name() -> &'static str {
  940. "fixunsdfdi"
  941. }
  942. fn generate<R>(rng: &mut R) -> Option<Self>
  943. where
  944. R: Rng,
  945. Self: Sized,
  946. {
  947. let a = gen_f64(rng);
  948. u64(a).ok().map(|b| Fixunsdfdi { a: to_u64(a), b })
  949. }
  950. fn to_string(&self, buffer: &mut String) {
  951. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  952. }
  953. fn prologue() -> &'static str {
  954. r#"
  955. #[cfg(all(target_arch = "arm",
  956. not(any(target_env = "gnu", target_env = "musl")),
  957. target_os = "linux",
  958. test))]
  959. use core::mem;
  960. #[cfg(not(all(target_arch = "arm",
  961. not(any(target_env = "gnu", target_env = "musl")),
  962. target_os = "linux",
  963. test)))]
  964. use std::mem;
  965. use compiler_builtins::float::conv::__fixunsdfdi;
  966. fn mk_f64(x: u64) -> f64 {
  967. unsafe { mem::transmute(x) }
  968. }
  969. static TEST_CASES: &[((u64,), u64)] = &[
  970. "#
  971. }
  972. fn epilogue() -> &'static str {
  973. "
  974. ];
  975. #[test]
  976. fn fixunsdfdi() {
  977. for &((a,), b) in TEST_CASES {
  978. let b_ = __fixunsdfdi(mk_f64(a));
  979. assert_eq!(((a,), b), ((a,), b_));
  980. }
  981. }
  982. "
  983. }
  984. }
  985. #[derive(Eq, Hash, PartialEq)]
  986. pub struct Fixunsdfsi {
  987. a: u64, // f64
  988. b: u32,
  989. }
  990. impl TestCase for Fixunsdfsi {
  991. fn name() -> &'static str {
  992. "fixunsdfsi"
  993. }
  994. fn generate<R>(rng: &mut R) -> Option<Self>
  995. where
  996. R: Rng,
  997. Self: Sized,
  998. {
  999. let a = gen_f64(rng);
  1000. u32(a).ok().map(|b| Fixunsdfsi { a: to_u64(a), b })
  1001. }
  1002. fn to_string(&self, buffer: &mut String) {
  1003. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  1004. }
  1005. fn prologue() -> &'static str {
  1006. r#"
  1007. #[cfg(all(target_arch = "arm",
  1008. not(any(target_env = "gnu", target_env = "musl")),
  1009. target_os = "linux",
  1010. test))]
  1011. use core::mem;
  1012. #[cfg(not(all(target_arch = "arm",
  1013. not(any(target_env = "gnu", target_env = "musl")),
  1014. target_os = "linux",
  1015. test)))]
  1016. use std::mem;
  1017. use compiler_builtins::float::conv::__fixunsdfsi;
  1018. fn mk_f64(x: u64) -> f64 {
  1019. unsafe { mem::transmute(x) }
  1020. }
  1021. static TEST_CASES: &[((u64,), u32)] = &[
  1022. "#
  1023. }
  1024. fn epilogue() -> &'static str {
  1025. "
  1026. ];
  1027. #[test]
  1028. fn fixunsdfdi() {
  1029. for &((a,), b) in TEST_CASES {
  1030. let b_ = __fixunsdfsi(mk_f64(a));
  1031. assert_eq!(((a,), b), ((a,), b_));
  1032. }
  1033. }
  1034. "
  1035. }
  1036. }
  1037. #[derive(Eq, Hash, PartialEq)]
  1038. pub struct Fixunssfdi {
  1039. a: u32, // f32
  1040. b: u64,
  1041. }
  1042. impl TestCase for Fixunssfdi {
  1043. fn name() -> &'static str {
  1044. "fixunssfdi"
  1045. }
  1046. fn generate<R>(rng: &mut R) -> Option<Self>
  1047. where
  1048. R: Rng,
  1049. Self: Sized,
  1050. {
  1051. let a = gen_f32(rng);
  1052. u64(a).ok().map(|b| Fixunssfdi { a: to_u32(a), b })
  1053. }
  1054. fn to_string(&self, buffer: &mut String) {
  1055. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  1056. }
  1057. fn prologue() -> &'static str {
  1058. r#"
  1059. #[cfg(all(target_arch = "arm",
  1060. not(any(target_env = "gnu", target_env = "musl")),
  1061. target_os = "linux",
  1062. test))]
  1063. use core::mem;
  1064. #[cfg(not(all(target_arch = "arm",
  1065. not(any(target_env = "gnu", target_env = "musl")),
  1066. target_os = "linux",
  1067. test)))]
  1068. use std::mem;
  1069. use compiler_builtins::float::conv::__fixunssfdi;
  1070. fn mk_f32(x: u32) -> f32 {
  1071. unsafe { mem::transmute(x) }
  1072. }
  1073. static TEST_CASES: &[((u32,), u64)] = &[
  1074. "#
  1075. }
  1076. fn epilogue() -> &'static str {
  1077. "
  1078. ];
  1079. #[test]
  1080. fn fixunssfdi() {
  1081. for &((a,), b) in TEST_CASES {
  1082. let b_ = __fixunssfdi(mk_f32(a));
  1083. assert_eq!(((a,), b), ((a,), b_));
  1084. }
  1085. }
  1086. "
  1087. }
  1088. }
  1089. #[derive(Eq, Hash, PartialEq)]
  1090. pub struct Fixunssfsi {
  1091. a: u32, // f32
  1092. b: u32,
  1093. }
  1094. impl TestCase for Fixunssfsi {
  1095. fn name() -> &'static str {
  1096. "fixunssfsi"
  1097. }
  1098. fn generate<R>(rng: &mut R) -> Option<Self>
  1099. where
  1100. R: Rng,
  1101. Self: Sized,
  1102. {
  1103. let a = gen_f32(rng);
  1104. u32(a).ok().map(|b| Fixunssfsi { a: to_u32(a), b })
  1105. }
  1106. fn to_string(&self, buffer: &mut String) {
  1107. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  1108. }
  1109. fn prologue() -> &'static str {
  1110. r#"
  1111. #[cfg(all(target_arch = "arm",
  1112. not(any(target_env = "gnu", target_env = "musl")),
  1113. target_os = "linux",
  1114. test))]
  1115. use core::mem;
  1116. #[cfg(not(all(target_arch = "arm",
  1117. not(any(target_env = "gnu", target_env = "musl")),
  1118. target_os = "linux",
  1119. test)))]
  1120. use std::mem;
  1121. use compiler_builtins::float::conv::__fixunssfsi;
  1122. fn mk_f32(x: u32) -> f32 {
  1123. unsafe { mem::transmute(x) }
  1124. }
  1125. static TEST_CASES: &[((u32,), u32)] = &[
  1126. "#
  1127. }
  1128. fn epilogue() -> &'static str {
  1129. "
  1130. ];
  1131. #[test]
  1132. fn fixunssfsi() {
  1133. for &((a,), b) in TEST_CASES {
  1134. let b_ = __fixunssfsi(mk_f32(a));
  1135. assert_eq!(((a,), b), ((a,), b_));
  1136. }
  1137. }
  1138. "
  1139. }
  1140. }
  1141. #[derive(Eq, Hash, PartialEq)]
  1142. pub struct Floatdidf {
  1143. a: i64,
  1144. b: u64, // f64
  1145. }
  1146. impl TestCase for Floatdidf {
  1147. fn name() -> &'static str {
  1148. "floatdidf"
  1149. }
  1150. fn generate<R>(rng: &mut R) -> Option<Self>
  1151. where
  1152. R: Rng,
  1153. Self: Sized,
  1154. {
  1155. let a = gen_i64(rng);
  1156. Some(
  1157. Floatdidf {
  1158. a,
  1159. b: to_u64(f64(a)),
  1160. },
  1161. )
  1162. }
  1163. fn to_string(&self, buffer: &mut String) {
  1164. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  1165. }
  1166. fn prologue() -> &'static str {
  1167. r#"
  1168. #[cfg(all(target_arch = "arm",
  1169. not(any(target_env = "gnu", target_env = "musl")),
  1170. target_os = "linux",
  1171. test))]
  1172. use core::mem;
  1173. #[cfg(not(all(target_arch = "arm",
  1174. not(any(target_env = "gnu", target_env = "musl")),
  1175. target_os = "linux",
  1176. test)))]
  1177. use std::mem;
  1178. use compiler_builtins::float::conv::__floatdidf;
  1179. fn mk_f64(x: u64) -> f64 {
  1180. unsafe { mem::transmute(x) }
  1181. }
  1182. static TEST_CASES: &[((i64,), u64)] = &[
  1183. "#
  1184. }
  1185. fn epilogue() -> &'static str {
  1186. "
  1187. ];
  1188. #[test]
  1189. fn floatdidf() {
  1190. for &((a,), b) in TEST_CASES {
  1191. let b_ = __floatdidf(a);
  1192. assert_eq!(((a,), mk_f64(b)), ((a,), b_));
  1193. }
  1194. }
  1195. "
  1196. }
  1197. }
  1198. #[derive(Eq, Hash, PartialEq)]
  1199. pub struct Floatsidf {
  1200. a: i32,
  1201. b: u64, // f64
  1202. }
  1203. impl TestCase for Floatsidf {
  1204. fn name() -> &'static str {
  1205. "floatsidf"
  1206. }
  1207. fn generate<R>(rng: &mut R) -> Option<Self>
  1208. where
  1209. R: Rng,
  1210. Self: Sized,
  1211. {
  1212. let a = gen_i32(rng);
  1213. Some(
  1214. Floatsidf {
  1215. a,
  1216. b: to_u64(f64(a)),
  1217. },
  1218. )
  1219. }
  1220. fn to_string(&self, buffer: &mut String) {
  1221. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  1222. }
  1223. fn prologue() -> &'static str {
  1224. r#"
  1225. #[cfg(all(target_arch = "arm",
  1226. not(any(target_env = "gnu", target_env = "musl")),
  1227. target_os = "linux",
  1228. test))]
  1229. use core::mem;
  1230. #[cfg(not(all(target_arch = "arm",
  1231. not(any(target_env = "gnu", target_env = "musl")),
  1232. target_os = "linux",
  1233. test)))]
  1234. use std::mem;
  1235. use compiler_builtins::float::conv::__floatsidf;
  1236. fn mk_f64(x: u64) -> f64 {
  1237. unsafe { mem::transmute(x) }
  1238. }
  1239. static TEST_CASES: &[((i32,), u64)] = &[
  1240. "#
  1241. }
  1242. fn epilogue() -> &'static str {
  1243. "
  1244. ];
  1245. #[test]
  1246. fn floatsidf() {
  1247. for &((a,), b) in TEST_CASES {
  1248. let b_ = __floatsidf(a);
  1249. assert_eq!(((a,), mk_f64(b)), ((a,), b_));
  1250. }
  1251. }
  1252. "
  1253. }
  1254. }
  1255. #[derive(Eq, Hash, PartialEq)]
  1256. pub struct Floatsisf {
  1257. a: i32,
  1258. b: u32, // f32
  1259. }
  1260. impl TestCase for Floatsisf {
  1261. fn name() -> &'static str {
  1262. "floatsisf"
  1263. }
  1264. fn generate<R>(rng: &mut R) -> Option<Self>
  1265. where
  1266. R: Rng,
  1267. Self: Sized,
  1268. {
  1269. let a = gen_i32(rng);
  1270. Some(
  1271. Floatsisf {
  1272. a,
  1273. b: to_u32(f32(a)),
  1274. },
  1275. )
  1276. }
  1277. fn to_string(&self, buffer: &mut String) {
  1278. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  1279. }
  1280. fn prologue() -> &'static str {
  1281. r#"
  1282. #[cfg(all(target_arch = "arm",
  1283. not(any(target_env = "gnu", target_env = "musl")),
  1284. target_os = "linux",
  1285. test))]
  1286. use core::mem;
  1287. #[cfg(not(all(target_arch = "arm",
  1288. not(any(target_env = "gnu", target_env = "musl")),
  1289. target_os = "linux",
  1290. test)))]
  1291. use std::mem;
  1292. use compiler_builtins::float::conv::__floatsisf;
  1293. fn mk_f32(x: u32) -> f32 {
  1294. unsafe { mem::transmute(x) }
  1295. }
  1296. static TEST_CASES: &[((i32,), u32)] = &[
  1297. "#
  1298. }
  1299. fn epilogue() -> &'static str {
  1300. "
  1301. ];
  1302. #[test]
  1303. fn floatsisf() {
  1304. for &((a,), b) in TEST_CASES {
  1305. let b_ = __floatsisf(a);
  1306. assert_eq!(((a,), mk_f32(b)), ((a,), b_));
  1307. }
  1308. }
  1309. "
  1310. }
  1311. }
  1312. #[derive(Eq, Hash, PartialEq)]
  1313. pub struct Floatundidf {
  1314. a: u64,
  1315. b: u64, // f64
  1316. }
  1317. impl TestCase for Floatundidf {
  1318. fn name() -> &'static str {
  1319. "floatundidf"
  1320. }
  1321. fn generate<R>(rng: &mut R) -> Option<Self>
  1322. where
  1323. R: Rng,
  1324. Self: Sized,
  1325. {
  1326. let a = gen_u64(rng);
  1327. Some(
  1328. Floatundidf {
  1329. a,
  1330. b: to_u64(f64(a)),
  1331. },
  1332. )
  1333. }
  1334. fn to_string(&self, buffer: &mut String) {
  1335. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  1336. }
  1337. fn prologue() -> &'static str {
  1338. r#"
  1339. #[cfg(all(target_arch = "arm",
  1340. not(any(target_env = "gnu", target_env = "musl")),
  1341. target_os = "linux",
  1342. test))]
  1343. use core::mem;
  1344. #[cfg(not(all(target_arch = "arm",
  1345. not(any(target_env = "gnu", target_env = "musl")),
  1346. target_os = "linux",
  1347. test)))]
  1348. use std::mem;
  1349. use compiler_builtins::float::conv::__floatundidf;
  1350. fn mk_f64(x: u64) -> f64 {
  1351. unsafe { mem::transmute(x) }
  1352. }
  1353. static TEST_CASES: &[((u64,), u64)] = &[
  1354. "#
  1355. }
  1356. fn epilogue() -> &'static str {
  1357. "
  1358. ];
  1359. #[test]
  1360. fn floatundidf() {
  1361. for &((a,), b) in TEST_CASES {
  1362. let b_ = __floatundidf(a);
  1363. assert_eq!(((a,), mk_f64(b)), ((a,), b_));
  1364. }
  1365. }
  1366. "
  1367. }
  1368. }
  1369. #[derive(Eq, Hash, PartialEq)]
  1370. pub struct Floatunsidf {
  1371. a: u32,
  1372. b: u64, // f64
  1373. }
  1374. impl TestCase for Floatunsidf {
  1375. fn name() -> &'static str {
  1376. "floatunsidf"
  1377. }
  1378. fn generate<R>(rng: &mut R) -> Option<Self>
  1379. where
  1380. R: Rng,
  1381. Self: Sized,
  1382. {
  1383. let a = gen_u32(rng);
  1384. Some(
  1385. Floatunsidf {
  1386. a,
  1387. b: to_u64(f64(a)),
  1388. },
  1389. )
  1390. }
  1391. fn to_string(&self, buffer: &mut String) {
  1392. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  1393. }
  1394. fn prologue() -> &'static str {
  1395. r#"
  1396. #[cfg(all(target_arch = "arm",
  1397. not(any(target_env = "gnu", target_env = "musl")),
  1398. target_os = "linux",
  1399. test))]
  1400. use core::mem;
  1401. #[cfg(not(all(target_arch = "arm",
  1402. not(any(target_env = "gnu", target_env = "musl")),
  1403. target_os = "linux",
  1404. test)))]
  1405. use std::mem;
  1406. use compiler_builtins::float::conv::__floatunsidf;
  1407. fn mk_f64(x: u64) -> f64 {
  1408. unsafe { mem::transmute(x) }
  1409. }
  1410. static TEST_CASES: &[((u32,), u64)] = &[
  1411. "#
  1412. }
  1413. fn epilogue() -> &'static str {
  1414. "
  1415. ];
  1416. #[test]
  1417. fn floatunsidf() {
  1418. for &((a,), b) in TEST_CASES {
  1419. let b_ = __floatunsidf(a);
  1420. assert_eq!(((a,), mk_f64(b)), ((a,), b_));
  1421. }
  1422. }
  1423. "
  1424. }
  1425. }
  1426. #[derive(Eq, Hash, PartialEq)]
  1427. pub struct Floatunsisf {
  1428. a: u32,
  1429. b: u32, // f32
  1430. }
  1431. impl TestCase for Floatunsisf {
  1432. fn name() -> &'static str {
  1433. "floatunsisf"
  1434. }
  1435. fn generate<R>(rng: &mut R) -> Option<Self>
  1436. where
  1437. R: Rng,
  1438. Self: Sized,
  1439. {
  1440. let a = gen_u32(rng);
  1441. Some(
  1442. Floatunsisf {
  1443. a,
  1444. b: to_u32(f32(a)),
  1445. },
  1446. )
  1447. }
  1448. fn to_string(&self, buffer: &mut String) {
  1449. writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
  1450. }
  1451. fn prologue() -> &'static str {
  1452. r#"
  1453. #[cfg(all(target_arch = "arm",
  1454. not(any(target_env = "gnu", target_env = "musl")),
  1455. target_os = "linux",
  1456. test))]
  1457. use core::mem;
  1458. #[cfg(not(all(target_arch = "arm",
  1459. not(any(target_env = "gnu", target_env = "musl")),
  1460. target_os = "linux",
  1461. test)))]
  1462. use std::mem;
  1463. use compiler_builtins::float::conv::__floatunsisf;
  1464. fn mk_f32(x: u32) -> f32 {
  1465. unsafe { mem::transmute(x) }
  1466. }
  1467. static TEST_CASES: &[((u32,), u32)] = &[
  1468. "#
  1469. }
  1470. fn epilogue() -> &'static str {
  1471. "
  1472. ];
  1473. #[test]
  1474. fn floatunsisf() {
  1475. for &((a,), b) in TEST_CASES {
  1476. let b_ = __floatunsisf(a);
  1477. assert_eq!(((a,), mk_f32(b)), ((a,), b_));
  1478. }
  1479. }
  1480. "
  1481. }
  1482. }
  1483. #[derive(Eq, Hash, PartialEq)]
  1484. pub struct Moddi3 {
  1485. a: i64,
  1486. b: i64,
  1487. c: i64,
  1488. }
  1489. impl TestCase for Moddi3 {
  1490. fn name() -> &'static str {
  1491. "moddi3"
  1492. }
  1493. fn generate<R>(rng: &mut R) -> Option<Self>
  1494. where
  1495. R: Rng,
  1496. Self: Sized,
  1497. {
  1498. let a = gen_i64(rng);
  1499. let b = gen_i64(rng);
  1500. if b == 0 {
  1501. return None;
  1502. }
  1503. let c = a % b;
  1504. Some(Moddi3 { a, b, c })
  1505. }
  1506. fn to_string(&self, buffer: &mut String) {
  1507. writeln!(
  1508. buffer,
  1509. "(({a}, {b}), {c}),",
  1510. a = self.a,
  1511. b = self.b,
  1512. c = self.c
  1513. )
  1514. .unwrap();
  1515. }
  1516. fn prologue() -> &'static str {
  1517. "
  1518. use compiler_builtins::int::sdiv::__moddi3;
  1519. static TEST_CASES: &[((i64, i64), i64)] = &[
  1520. "
  1521. }
  1522. fn epilogue() -> &'static str {
  1523. "
  1524. ];
  1525. #[test]
  1526. fn moddi3() {
  1527. for &((a, b), c) in TEST_CASES {
  1528. let c_ = __moddi3(a, b);
  1529. assert_eq!(((a, b), c), ((a, b), c_));
  1530. }
  1531. }
  1532. "
  1533. }
  1534. }
  1535. #[derive(Eq, Hash, PartialEq)]
  1536. pub struct Modsi3 {
  1537. a: i32,
  1538. b: i32,
  1539. c: i32,
  1540. }
  1541. impl TestCase for Modsi3 {
  1542. fn name() -> &'static str {
  1543. "modsi3"
  1544. }
  1545. fn generate<R>(rng: &mut R) -> Option<Self>
  1546. where
  1547. R: Rng,
  1548. Self: Sized,
  1549. {
  1550. let a = gen_i32(rng);
  1551. let b = gen_i32(rng);
  1552. if b == 0 {
  1553. return None;
  1554. }
  1555. let c = a % b;
  1556. Some(Modsi3 { a, b, c })
  1557. }
  1558. fn to_string(&self, buffer: &mut String) {
  1559. writeln!(
  1560. buffer,
  1561. "(({a}, {b}), {c}),",
  1562. a = self.a,
  1563. b = self.b,
  1564. c = self.c
  1565. )
  1566. .unwrap();
  1567. }
  1568. fn prologue() -> &'static str {
  1569. "
  1570. use compiler_builtins::int::sdiv::__modsi3;
  1571. static TEST_CASES: &[((i32, i32), i32)] = &[
  1572. "
  1573. }
  1574. fn epilogue() -> &'static str {
  1575. "
  1576. ];
  1577. #[test]
  1578. fn modsi3() {
  1579. for &((a, b), c) in TEST_CASES {
  1580. let c_ = __modsi3(a, b);
  1581. assert_eq!(((a, b), c), ((a, b), c_));
  1582. }
  1583. }
  1584. "
  1585. }
  1586. }
  1587. #[derive(Eq, Hash, PartialEq)]
  1588. pub struct Modti3 {
  1589. a: i128,
  1590. b: i128,
  1591. c: i128,
  1592. }
  1593. impl TestCase for Modti3 {
  1594. fn name() -> &'static str {
  1595. "modti3"
  1596. }
  1597. fn generate<R>(rng: &mut R) -> Option<Self>
  1598. where
  1599. R: Rng,
  1600. Self: Sized,
  1601. {
  1602. let a = gen_i128(rng);
  1603. let b = gen_i128(rng);
  1604. if b == 0 {
  1605. return None;
  1606. }
  1607. let c = a % b;
  1608. Some(Modti3 { a, b, c })
  1609. }
  1610. fn to_string(&self, buffer: &mut String) {
  1611. writeln!(
  1612. buffer,
  1613. "(({a}, {b}), {c}),",
  1614. a = self.a,
  1615. b = self.b,
  1616. c = self.c
  1617. )
  1618. .unwrap();
  1619. }
  1620. fn prologue() -> &'static str {
  1621. "
  1622. use compiler_builtins::int::sdiv::__modti3;
  1623. static TEST_CASES: &[((i128, i128), i128)] = &[
  1624. "
  1625. }
  1626. fn epilogue() -> &'static str {
  1627. "
  1628. ];
  1629. #[test]
  1630. fn modti3() {
  1631. for &((a, b), c) in TEST_CASES {
  1632. let c_ = __modti3(a, b);
  1633. assert_eq!(((a, b), c), ((a, b), c_));
  1634. }
  1635. }
  1636. "
  1637. }
  1638. }
  1639. #[derive(Eq, Hash, PartialEq)]
  1640. struct Muldi3 {
  1641. a: u64,
  1642. b: u64,
  1643. c: u64,
  1644. }
  1645. impl TestCase for Muldi3 {
  1646. fn name() -> &'static str {
  1647. "muldi3"
  1648. }
  1649. fn generate<R>(rng: &mut R) -> Option<Self>
  1650. where
  1651. R: Rng,
  1652. Self: Sized,
  1653. {
  1654. let a = gen_u64(rng);
  1655. let b = gen_u64(rng);
  1656. let c = a.wrapping_mul(b);
  1657. Some(Muldi3 { a, b, c })
  1658. }
  1659. fn to_string(&self, buffer: &mut String) {
  1660. writeln!(
  1661. buffer,
  1662. "(({a}, {b}), {c}),",
  1663. a = self.a,
  1664. b = self.b,
  1665. c = self.c
  1666. )
  1667. .unwrap();
  1668. }
  1669. fn prologue() -> &'static str {
  1670. "
  1671. use compiler_builtins::int::mul::__muldi3;
  1672. static TEST_CASES: &[((u64, u64), u64)] = &[
  1673. "
  1674. }
  1675. fn epilogue() -> &'static str {
  1676. "
  1677. ];
  1678. #[test]
  1679. fn muldi3() {
  1680. for &((a, b), c) in TEST_CASES {
  1681. let c_ = __muldi3(a, b);
  1682. assert_eq!(((a, b), c), ((a, b), c_));
  1683. }
  1684. }
  1685. "
  1686. }
  1687. }
  1688. #[derive(Eq, Hash, PartialEq)]
  1689. pub struct Mulodi4 {
  1690. a: i64,
  1691. b: i64,
  1692. c: i64,
  1693. overflow: u32,
  1694. }
  1695. impl TestCase for Mulodi4 {
  1696. fn name() -> &'static str {
  1697. "mulodi4"
  1698. }
  1699. fn generate<R>(rng: &mut R) -> Option<Self>
  1700. where
  1701. R: Rng,
  1702. {
  1703. let a = gen_i64(rng);
  1704. let b = gen_i64(rng);
  1705. let c = a.wrapping_mul(b);
  1706. let overflow = if a.checked_mul(b).is_some() { 0 } else { 1 };
  1707. Some(Mulodi4 { a, b, c, overflow })
  1708. }
  1709. fn to_string(&self, buffer: &mut String) {
  1710. writeln!(
  1711. buffer,
  1712. "(({a}, {b}), ({c}, {overflow})),",
  1713. a = self.a,
  1714. b = self.b,
  1715. c = self.c,
  1716. overflow = self.overflow
  1717. )
  1718. .unwrap();
  1719. }
  1720. fn prologue() -> &'static str {
  1721. "
  1722. use compiler_builtins::int::mul::__mulodi4;
  1723. static TEST_CASES: &[((i64, i64), (i64, i32))] = &[
  1724. "
  1725. }
  1726. fn epilogue() -> &'static str {
  1727. "
  1728. ];
  1729. #[test]
  1730. fn mulodi4() {
  1731. let mut overflow_ = 2;
  1732. for &((a, b), (c, overflow)) in TEST_CASES {
  1733. let c_ = __mulodi4(a, b, &mut overflow_);
  1734. assert_eq!(((a, b), (c, overflow)), ((a, b), (c_, overflow_)));
  1735. }
  1736. }
  1737. "
  1738. }
  1739. }
  1740. #[derive(Eq, Hash, PartialEq)]
  1741. pub struct Mulosi4 {
  1742. a: i32,
  1743. b: i32,
  1744. c: i32,
  1745. overflow: u32,
  1746. }
  1747. impl TestCase for Mulosi4 {
  1748. fn name() -> &'static str {
  1749. "mulosi4"
  1750. }
  1751. fn generate<R>(rng: &mut R) -> Option<Self>
  1752. where
  1753. R: Rng,
  1754. {
  1755. let a = gen_i32(rng);
  1756. let b = gen_i32(rng);
  1757. let c = a.wrapping_mul(b);
  1758. let overflow = if a.checked_mul(b).is_some() { 0 } else { 1 };
  1759. Some(Mulosi4 { a, b, c, overflow })
  1760. }
  1761. fn prologue() -> &'static str {
  1762. "
  1763. use compiler_builtins::int::mul::__mulosi4;
  1764. static TEST_CASES: &[((i32, i32), (i32, i32))] = &[
  1765. "
  1766. }
  1767. fn epilogue() -> &'static str {
  1768. "
  1769. ];
  1770. #[test]
  1771. fn mulosi4() {
  1772. let mut overflow_ = 2;
  1773. for &((a, b), (c, overflow)) in TEST_CASES {
  1774. let c_ = __mulosi4(a, b, &mut overflow_);
  1775. assert_eq!(((a, b), (c, overflow)), ((a, b), (c_, overflow_)));
  1776. }
  1777. }
  1778. "
  1779. }
  1780. fn to_string(&self, buffer: &mut String) {
  1781. writeln!(
  1782. buffer,
  1783. "(({a}, {b}), ({c}, {overflow})),",
  1784. a = self.a,
  1785. b = self.b,
  1786. c = self.c,
  1787. overflow = self.overflow
  1788. )
  1789. .unwrap();
  1790. }
  1791. }
  1792. #[derive(Eq, Hash, PartialEq)]
  1793. pub struct Muloti4 {
  1794. a: i128,
  1795. b: i128,
  1796. c: i128,
  1797. overflow: u32,
  1798. }
  1799. impl TestCase for Muloti4 {
  1800. fn name() -> &'static str {
  1801. "muloti4"
  1802. }
  1803. fn generate<R>(rng: &mut R) -> Option<Self>
  1804. where
  1805. R: Rng,
  1806. {
  1807. let a = gen_i128(rng);
  1808. let b = gen_i128(rng);
  1809. let c = a.wrapping_mul(b);
  1810. let overflow = if a.checked_mul(b).is_some() { 0 } else { 1 };
  1811. Some(Muloti4 { a, b, c, overflow })
  1812. }
  1813. fn prologue() -> &'static str {
  1814. "
  1815. use compiler_builtins::int::mul::__muloti4;
  1816. static TEST_CASES: &[((i128, i128), (i128, i32))] = &[
  1817. "
  1818. }
  1819. fn epilogue() -> &'static str {
  1820. "
  1821. ];
  1822. #[test]
  1823. fn muloti4() {
  1824. let mut overflow_ = 2;
  1825. for &((a, b), (c, overflow)) in TEST_CASES {
  1826. let c_ = __muloti4(a, b, &mut overflow_);
  1827. assert_eq!(((a, b), (c, overflow)), ((a, b), (c_, overflow_)));
  1828. }
  1829. }
  1830. "
  1831. }
  1832. fn to_string(&self, buffer: &mut String) {
  1833. writeln!(
  1834. buffer,
  1835. "(({a}, {b}), ({c}, {overflow})),",
  1836. a = self.a,
  1837. b = self.b,
  1838. c = self.c,
  1839. overflow = self.overflow
  1840. )
  1841. .unwrap();
  1842. }
  1843. }
  1844. #[derive(Eq, Hash, PartialEq)]
  1845. pub struct Multi3 {
  1846. a: i128,
  1847. b: i128,
  1848. c: i128,
  1849. }
  1850. impl TestCase for Multi3 {
  1851. fn name() -> &'static str {
  1852. "multi3"
  1853. }
  1854. fn generate<R>(rng: &mut R) -> Option<Self>
  1855. where
  1856. R: Rng,
  1857. Self: Sized,
  1858. {
  1859. let a = gen_i128(rng);
  1860. let b = gen_i128(rng);
  1861. let c = a.wrapping_mul(b);
  1862. Some(Multi3 { a, b, c })
  1863. }
  1864. fn to_string(&self, buffer: &mut String) {
  1865. writeln!(
  1866. buffer,
  1867. "(({a}, {b}), {c}),",
  1868. a = self.a,
  1869. b = self.b,
  1870. c = self.c
  1871. )
  1872. .unwrap();
  1873. }
  1874. fn prologue() -> &'static str {
  1875. "
  1876. use compiler_builtins::int::mul::__multi3;
  1877. static TEST_CASES: &[((i128, i128), i128)] = &[
  1878. "
  1879. }
  1880. fn epilogue() -> &'static str {
  1881. "
  1882. ];
  1883. #[test]
  1884. fn multi3() {
  1885. for &((a, b), c) in TEST_CASES {
  1886. let c_ = __multi3(a, b);
  1887. assert_eq!(((a, b), c), ((a, b), c_));
  1888. }
  1889. }
  1890. "
  1891. }
  1892. }
  1893. #[derive(Eq, Hash, PartialEq)]
  1894. pub struct Powidf2 {
  1895. a: u64, // f64
  1896. b: i32,
  1897. c: u64, // f64
  1898. }
  1899. impl TestCase for Powidf2 {
  1900. fn name() -> &'static str {
  1901. "powidf2"
  1902. }
  1903. fn generate<R>(rng: &mut R) -> Option<Self>
  1904. where
  1905. R: Rng,
  1906. Self: Sized,
  1907. {
  1908. let a = gen_f64(rng);
  1909. let b = gen_i32(rng);
  1910. let c = a.powi(b);
  1911. // TODO accept NaNs. We don't do that right now because we can't check
  1912. // for NaN-ness on the thumb targets
  1913. if a.is_nan() || c.is_nan() {
  1914. return None;
  1915. }
  1916. Some(
  1917. Powidf2 {
  1918. a: to_u64(a),
  1919. b,
  1920. c: to_u64(c),
  1921. },
  1922. )
  1923. }
  1924. fn to_string(&self, buffer: &mut String) {
  1925. writeln!(
  1926. buffer,
  1927. "(({a}, {b}), {c}),",
  1928. a = self.a,
  1929. b = self.b,
  1930. c = self.c
  1931. )
  1932. .unwrap();
  1933. }
  1934. fn prologue() -> &'static str {
  1935. r#"
  1936. #[cfg(all(target_arch = "arm",
  1937. not(any(target_env = "gnu", target_env = "musl")),
  1938. target_os = "linux",
  1939. test))]
  1940. use core::mem;
  1941. #[cfg(not(all(target_arch = "arm",
  1942. not(any(target_env = "gnu", target_env = "musl")),
  1943. target_os = "linux",
  1944. test)))]
  1945. use std::mem;
  1946. use compiler_builtins::float::pow::__powidf2;
  1947. fn mk_f64(x: u64) -> f64 {
  1948. unsafe { mem::transmute(x) }
  1949. }
  1950. fn to_u64(x: f64) -> u64 {
  1951. unsafe { mem::transmute(x) }
  1952. }
  1953. static TEST_CASES: &[((u64, i32), u64)] = &[
  1954. "#
  1955. }
  1956. fn epilogue() -> &'static str {
  1957. "
  1958. ];
  1959. #[test]
  1960. fn powidf2() {
  1961. for &((a, b), c) in TEST_CASES {
  1962. let c_ = __powidf2(mk_f64(a), b);
  1963. assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
  1964. }
  1965. }
  1966. "
  1967. }
  1968. }
  1969. #[derive(Eq, Hash, PartialEq)]
  1970. pub struct Powisf2 {
  1971. a: u32, // f32
  1972. b: i32,
  1973. c: u32, // f32
  1974. }
  1975. impl TestCase for Powisf2 {
  1976. fn name() -> &'static str {
  1977. "powisf2"
  1978. }
  1979. fn generate<R>(rng: &mut R) -> Option<Self>
  1980. where
  1981. R: Rng,
  1982. Self: Sized,
  1983. {
  1984. let a = gen_f32(rng);
  1985. let b = gen_i32(rng);
  1986. let c = a.powi(b);
  1987. // TODO accept NaNs. We don't do that right now because we can't check
  1988. // for NaN-ness on the thumb targets
  1989. if a.is_nan() || c.is_nan() {
  1990. return None;
  1991. }
  1992. Some(
  1993. Powisf2 {
  1994. a: to_u32(a),
  1995. b,
  1996. c: to_u32(c),
  1997. },
  1998. )
  1999. }
  2000. fn to_string(&self, buffer: &mut String) {
  2001. writeln!(
  2002. buffer,
  2003. "(({a}, {b}), {c}),",
  2004. a = self.a,
  2005. b = self.b,
  2006. c = self.c
  2007. )
  2008. .unwrap();
  2009. }
  2010. fn prologue() -> &'static str {
  2011. r#"
  2012. #[cfg(all(target_arch = "arm",
  2013. not(any(target_env = "gnu", target_env = "musl")),
  2014. target_os = "linux",
  2015. test))]
  2016. use core::mem;
  2017. #[cfg(not(all(target_arch = "arm",
  2018. not(any(target_env = "gnu", target_env = "musl")),
  2019. target_os = "linux",
  2020. test)))]
  2021. use std::mem;
  2022. use compiler_builtins::float::pow::__powisf2;
  2023. fn mk_f32(x: u32) -> f32 {
  2024. unsafe { mem::transmute(x) }
  2025. }
  2026. fn to_u32(x: f32) -> u32 {
  2027. unsafe { mem::transmute(x) }
  2028. }
  2029. static TEST_CASES: &[((u32, i32), u32)] = &[
  2030. "#
  2031. }
  2032. fn epilogue() -> &'static str {
  2033. "
  2034. ];
  2035. #[test]
  2036. fn powisf2() {
  2037. for &((a, b), c) in TEST_CASES {
  2038. let c_ = __powisf2(mk_f32(a), b);
  2039. assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
  2040. }
  2041. }
  2042. "
  2043. }
  2044. }
  2045. #[derive(Eq, Hash, PartialEq)]
  2046. pub struct Lshrdi3 {
  2047. a: u64,
  2048. b: u32,
  2049. c: u64,
  2050. }
  2051. impl TestCase for Lshrdi3 {
  2052. fn name() -> &'static str {
  2053. "lshrdi3"
  2054. }
  2055. fn generate<R>(rng: &mut R) -> Option<Self>
  2056. where
  2057. R: Rng,
  2058. Self: Sized,
  2059. {
  2060. let a = gen_u64(rng);
  2061. let b = (rng.gen::<u8>() % 64) as u32;
  2062. let c = a >> b;
  2063. Some(Lshrdi3 { a, b, c })
  2064. }
  2065. fn to_string(&self, buffer: &mut String) {
  2066. writeln!(
  2067. buffer,
  2068. "(({a}, {b}), {c}),",
  2069. a = self.a,
  2070. b = self.b,
  2071. c = self.c
  2072. )
  2073. .unwrap();
  2074. }
  2075. fn prologue() -> &'static str {
  2076. "
  2077. use compiler_builtins::int::shift::__lshrdi3;
  2078. static TEST_CASES: &[((u64, u32), u64)] = &[
  2079. "
  2080. }
  2081. fn epilogue() -> &'static str {
  2082. "
  2083. ];
  2084. #[test]
  2085. fn lshrdi3() {
  2086. for &((a, b), c) in TEST_CASES {
  2087. let c_ = __lshrdi3(a, b);
  2088. assert_eq!(((a, b), c), ((a, b), c_));
  2089. }
  2090. }
  2091. "
  2092. }
  2093. }
  2094. #[derive(Eq, Hash, PartialEq)]
  2095. pub struct Lshrti3 {
  2096. a: u128,
  2097. b: u32,
  2098. c: u128,
  2099. }
  2100. impl TestCase for Lshrti3 {
  2101. fn name() -> &'static str {
  2102. "lshrti3"
  2103. }
  2104. fn generate<R>(rng: &mut R) -> Option<Self>
  2105. where
  2106. R: Rng,
  2107. Self: Sized,
  2108. {
  2109. let a = gen_u128(rng);
  2110. let b = (rng.gen::<u8>() % 128) as u32;
  2111. let c = a >> b;
  2112. Some(Lshrti3 { a, b, c })
  2113. }
  2114. fn to_string(&self, buffer: &mut String) {
  2115. writeln!(
  2116. buffer,
  2117. "(({a}, {b}), {c}),",
  2118. a = self.a,
  2119. b = self.b,
  2120. c = self.c
  2121. )
  2122. .unwrap();
  2123. }
  2124. fn prologue() -> &'static str {
  2125. "
  2126. use compiler_builtins::int::shift::__lshrti3;
  2127. static TEST_CASES: &[((u128, u32), u128)] = &[
  2128. "
  2129. }
  2130. fn epilogue() -> &'static str {
  2131. "
  2132. ];
  2133. #[test]
  2134. fn lshrti3() {
  2135. for &((a, b), c) in TEST_CASES {
  2136. let c_ = __lshrti3(a, b);
  2137. assert_eq!(((a, b), c), ((a, b), c_));
  2138. }
  2139. }
  2140. "
  2141. }
  2142. }
  2143. #[derive(Eq, Hash, PartialEq)]
  2144. pub struct Subdf3 {
  2145. a: u64, // f64
  2146. b: u64, // f64
  2147. c: u64, // f64
  2148. }
  2149. impl TestCase for Subdf3 {
  2150. fn name() -> &'static str {
  2151. "subdf3"
  2152. }
  2153. fn generate<R>(rng: &mut R) -> Option<Self>
  2154. where
  2155. R: Rng,
  2156. Self: Sized,
  2157. {
  2158. let a = gen_f64(rng);
  2159. let b = gen_f64(rng);
  2160. let c = a - b;
  2161. // TODO accept NaNs. We don't do that right now because we can't check
  2162. // for NaN-ness on the thumb targets (due to missing intrinsics)
  2163. if a.is_nan() || b.is_nan() || c.is_nan() {
  2164. return None;
  2165. }
  2166. Some(
  2167. Subdf3 {
  2168. a: to_u64(a),
  2169. b: to_u64(b),
  2170. c: to_u64(c),
  2171. },
  2172. )
  2173. }
  2174. fn to_string(&self, buffer: &mut String) {
  2175. writeln!(
  2176. buffer,
  2177. "(({a}, {b}), {c}),",
  2178. a = self.a,
  2179. b = self.b,
  2180. c = self.c
  2181. )
  2182. .unwrap();
  2183. }
  2184. fn prologue() -> &'static str {
  2185. r#"
  2186. #[cfg(all(target_arch = "arm",
  2187. not(any(target_env = "gnu", target_env = "musl")),
  2188. target_os = "linux",
  2189. test))]
  2190. use core::mem;
  2191. #[cfg(not(all(target_arch = "arm",
  2192. not(any(target_env = "gnu", target_env = "musl")),
  2193. target_os = "linux",
  2194. test)))]
  2195. use std::mem;
  2196. use compiler_builtins::float::sub::__subdf3;
  2197. fn mk_f64(x: u64) -> f64 {
  2198. unsafe { mem::transmute(x) }
  2199. }
  2200. fn to_u64(x: f64) -> u64 {
  2201. unsafe { mem::transmute(x) }
  2202. }
  2203. static TEST_CASES: &[((u64, u64), u64)] = &[
  2204. "#
  2205. }
  2206. fn epilogue() -> &'static str {
  2207. "
  2208. ];
  2209. #[test]
  2210. fn subdf3() {
  2211. for &((a, b), c) in TEST_CASES {
  2212. let c_ = __subdf3(mk_f64(a), mk_f64(b));
  2213. assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
  2214. }
  2215. }
  2216. "
  2217. }
  2218. }
  2219. #[derive(Eq, Hash, PartialEq)]
  2220. pub struct Subsf3 {
  2221. a: u32, // f32
  2222. b: u32, // f32
  2223. c: u32, // f32
  2224. }
  2225. impl TestCase for Subsf3 {
  2226. fn name() -> &'static str {
  2227. "subsf3"
  2228. }
  2229. fn generate<R>(rng: &mut R) -> Option<Self>
  2230. where
  2231. R: Rng,
  2232. Self: Sized,
  2233. {
  2234. let a = gen_f32(rng);
  2235. let b = gen_f32(rng);
  2236. let c = a - b;
  2237. // TODO accept NaNs. We don't do that right now because we can't check
  2238. // for NaN-ness on the thumb targets (due to missing intrinsics)
  2239. if a.is_nan() || b.is_nan() || c.is_nan() {
  2240. return None;
  2241. }
  2242. Some(
  2243. Subsf3 {
  2244. a: to_u32(a),
  2245. b: to_u32(b),
  2246. c: to_u32(c),
  2247. },
  2248. )
  2249. }
  2250. fn to_string(&self, buffer: &mut String) {
  2251. writeln!(
  2252. buffer,
  2253. "(({a}, {b}), {c}),",
  2254. a = self.a,
  2255. b = self.b,
  2256. c = self.c
  2257. )
  2258. .unwrap();
  2259. }
  2260. fn prologue() -> &'static str {
  2261. r#"
  2262. #[cfg(all(target_arch = "arm",
  2263. not(any(target_env = "gnu", target_env = "musl")),
  2264. target_os = "linux",
  2265. test))]
  2266. use core::mem;
  2267. #[cfg(not(all(target_arch = "arm",
  2268. not(any(target_env = "gnu", target_env = "musl")),
  2269. target_os = "linux",
  2270. test)))]
  2271. use std::mem;
  2272. use compiler_builtins::float::sub::__subsf3;
  2273. fn mk_f32(x: u32) -> f32 {
  2274. unsafe { mem::transmute(x) }
  2275. }
  2276. fn to_u32(x: f32) -> u32 {
  2277. unsafe { mem::transmute(x) }
  2278. }
  2279. static TEST_CASES: &[((u32, u32), u32)] = &[
  2280. "#
  2281. }
  2282. fn epilogue() -> &'static str {
  2283. "
  2284. ];
  2285. #[test]
  2286. fn subsf3() {
  2287. for &((a, b), c) in TEST_CASES {
  2288. let c_ = __subsf3(mk_f32(a), mk_f32(b));
  2289. assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
  2290. }
  2291. }
  2292. "
  2293. }
  2294. }
  2295. #[derive(Eq, Hash, PartialEq)]
  2296. pub struct Udivdi3 {
  2297. a: u64,
  2298. b: u64,
  2299. c: u64,
  2300. }
  2301. impl TestCase for Udivdi3 {
  2302. fn name() -> &'static str {
  2303. "udivdi3"
  2304. }
  2305. fn generate<R>(rng: &mut R) -> Option<Self>
  2306. where
  2307. R: Rng,
  2308. Self: Sized,
  2309. {
  2310. let a = gen_u64(rng);
  2311. let b = gen_u64(rng);
  2312. if b == 0 {
  2313. return None;
  2314. }
  2315. let c = a / b;
  2316. Some(Udivdi3 { a, b, c })
  2317. }
  2318. fn to_string(&self, buffer: &mut String) {
  2319. writeln!(
  2320. buffer,
  2321. "(({a}, {b}), {c}),",
  2322. a = self.a,
  2323. b = self.b,
  2324. c = self.c
  2325. )
  2326. .unwrap();
  2327. }
  2328. fn prologue() -> &'static str {
  2329. "
  2330. use compiler_builtins::int::udiv::__udivdi3;
  2331. static TEST_CASES: &[((u64, u64), u64)] = &[
  2332. "
  2333. }
  2334. fn epilogue() -> &'static str {
  2335. "
  2336. ];
  2337. #[test]
  2338. fn udivdi3() {
  2339. for &((a, b), c) in TEST_CASES {
  2340. let c_ = __udivdi3(a, b);
  2341. assert_eq!(((a, b), c), ((a, b), c_));
  2342. }
  2343. }
  2344. "
  2345. }
  2346. }
  2347. #[derive(Eq, Hash, PartialEq)]
  2348. pub struct Udivmoddi4 {
  2349. a: u64,
  2350. b: u64,
  2351. c: u64,
  2352. rem: u64,
  2353. }
  2354. impl TestCase for Udivmoddi4 {
  2355. fn name() -> &'static str {
  2356. "udivmoddi4"
  2357. }
  2358. fn generate<R>(rng: &mut R) -> Option<Self>
  2359. where
  2360. R: Rng,
  2361. Self: Sized,
  2362. {
  2363. let a = gen_u64(rng);
  2364. let b = gen_u64(rng);
  2365. if b == 0 {
  2366. return None;
  2367. }
  2368. let c = a / b;
  2369. let rem = a % b;
  2370. Some(Udivmoddi4 { a, b, c, rem })
  2371. }
  2372. fn to_string(&self, buffer: &mut String) {
  2373. writeln!(
  2374. buffer,
  2375. "(({a}, {b}), ({c}, {rem})),",
  2376. a = self.a,
  2377. b = self.b,
  2378. c = self.c,
  2379. rem = self.rem
  2380. )
  2381. .unwrap();
  2382. }
  2383. fn prologue() -> &'static str {
  2384. "
  2385. use compiler_builtins::int::udiv::__udivmoddi4;
  2386. static TEST_CASES: &[((u64, u64), (u64, u64))] = &[
  2387. "
  2388. }
  2389. fn epilogue() -> &'static str {
  2390. "
  2391. ];
  2392. #[test]
  2393. fn udivmoddi4() {
  2394. for &((a, b), (c, rem)) in TEST_CASES {
  2395. let mut rem_ = 0;
  2396. let c_ = __udivmoddi4(a, b, Some(&mut rem_));
  2397. assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
  2398. }
  2399. }
  2400. "
  2401. }
  2402. }
  2403. #[derive(Eq, Hash, PartialEq)]
  2404. pub struct Udivmodsi4 {
  2405. a: u32,
  2406. b: u32,
  2407. c: u32,
  2408. rem: u32,
  2409. }
  2410. impl TestCase for Udivmodsi4 {
  2411. fn name() -> &'static str {
  2412. "udivmodsi4"
  2413. }
  2414. fn generate<R>(rng: &mut R) -> Option<Self>
  2415. where
  2416. R: Rng,
  2417. Self: Sized,
  2418. {
  2419. let a = gen_u32(rng);
  2420. let b = gen_u32(rng);
  2421. if b == 0 {
  2422. return None;
  2423. }
  2424. let c = a / b;
  2425. let rem = a % b;
  2426. Some(Udivmodsi4 { a, b, c, rem })
  2427. }
  2428. fn to_string(&self, buffer: &mut String) {
  2429. writeln!(
  2430. buffer,
  2431. "(({a}, {b}), ({c}, {rem})),",
  2432. a = self.a,
  2433. b = self.b,
  2434. c = self.c,
  2435. rem = self.rem
  2436. )
  2437. .unwrap();
  2438. }
  2439. fn prologue() -> &'static str {
  2440. "
  2441. use compiler_builtins::int::udiv::__udivmodsi4;
  2442. static TEST_CASES: &[((u32, u32), (u32, u32))] = &[
  2443. "
  2444. }
  2445. fn epilogue() -> &'static str {
  2446. "
  2447. ];
  2448. #[test]
  2449. fn udivmodsi4() {
  2450. for &((a, b), (c, rem)) in TEST_CASES {
  2451. let mut rem_ = 0;
  2452. let c_ = __udivmodsi4(a, b, Some(&mut rem_));
  2453. assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
  2454. }
  2455. }
  2456. "
  2457. }
  2458. }
  2459. #[derive(Eq, Hash, PartialEq)]
  2460. pub struct Udivmodti4 {
  2461. a: u128,
  2462. b: u128,
  2463. c: u128,
  2464. rem: u128,
  2465. }
  2466. impl TestCase for Udivmodti4 {
  2467. fn name() -> &'static str {
  2468. "udivmodti4"
  2469. }
  2470. fn generate<R>(rng: &mut R) -> Option<Self>
  2471. where
  2472. R: Rng,
  2473. Self: Sized,
  2474. {
  2475. let a = gen_u128(rng);
  2476. let b = gen_u128(rng);
  2477. if b == 0 {
  2478. return None;
  2479. }
  2480. let c = a / b;
  2481. let rem = a % b;
  2482. Some(Udivmodti4 { a, b, c, rem })
  2483. }
  2484. fn to_string(&self, buffer: &mut String) {
  2485. writeln!(
  2486. buffer,
  2487. "(({a}, {b}), ({c}, {rem})),",
  2488. a = self.a,
  2489. b = self.b,
  2490. c = self.c,
  2491. rem = self.rem
  2492. )
  2493. .unwrap();
  2494. }
  2495. fn prologue() -> &'static str {
  2496. "
  2497. use compiler_builtins::int::udiv::__udivmodti4;
  2498. static TEST_CASES: &[((u128, u128), (u128, u128))] = &[
  2499. "
  2500. }
  2501. fn epilogue() -> &'static str {
  2502. "
  2503. ];
  2504. #[test]
  2505. fn udivmodti4() {
  2506. for &((a, b), (c, rem)) in TEST_CASES {
  2507. let mut rem_ = 0;
  2508. let c_ = __udivmodti4(a, b, Some(&mut rem_));
  2509. assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
  2510. }
  2511. }
  2512. "
  2513. }
  2514. }
  2515. #[derive(Eq, Hash, PartialEq)]
  2516. pub struct Udivsi3 {
  2517. a: u32,
  2518. b: u32,
  2519. c: u32,
  2520. }
  2521. impl TestCase for Udivsi3 {
  2522. fn name() -> &'static str {
  2523. "udivsi3"
  2524. }
  2525. fn generate<R>(rng: &mut R) -> Option<Self>
  2526. where
  2527. R: Rng,
  2528. Self: Sized,
  2529. {
  2530. let a = gen_u32(rng);
  2531. let b = gen_u32(rng);
  2532. if b == 0 {
  2533. return None;
  2534. }
  2535. let c = a / b;
  2536. Some(Udivsi3 { a, b, c })
  2537. }
  2538. fn to_string(&self, buffer: &mut String) {
  2539. writeln!(
  2540. buffer,
  2541. "(({a}, {b}), {c}),",
  2542. a = self.a,
  2543. b = self.b,
  2544. c = self.c
  2545. )
  2546. .unwrap();
  2547. }
  2548. fn prologue() -> &'static str {
  2549. "
  2550. use compiler_builtins::int::udiv::__udivsi3;
  2551. static TEST_CASES: &[((u32, u32), u32)] = &[
  2552. "
  2553. }
  2554. fn epilogue() -> &'static str {
  2555. "
  2556. ];
  2557. #[test]
  2558. fn udivsi3() {
  2559. for &((a, b), c) in TEST_CASES {
  2560. let c_ = __udivsi3(a, b);
  2561. assert_eq!(((a, b), c), ((a, b), c_));
  2562. }
  2563. }
  2564. "
  2565. }
  2566. }
  2567. #[derive(Eq, Hash, PartialEq)]
  2568. pub struct Udivti3 {
  2569. a: u128,
  2570. b: u128,
  2571. c: u128,
  2572. }
  2573. impl TestCase for Udivti3 {
  2574. fn name() -> &'static str {
  2575. "udivti3"
  2576. }
  2577. fn generate<R>(rng: &mut R) -> Option<Self>
  2578. where
  2579. R: Rng,
  2580. Self: Sized,
  2581. {
  2582. let a = gen_u128(rng);
  2583. let b = gen_u128(rng);
  2584. if b == 0 {
  2585. return None;
  2586. }
  2587. let c = a / b;
  2588. Some(Udivti3 { a, b, c })
  2589. }
  2590. fn to_string(&self, buffer: &mut String) {
  2591. writeln!(
  2592. buffer,
  2593. "(({a}, {b}), {c}),",
  2594. a = self.a,
  2595. b = self.b,
  2596. c = self.c
  2597. )
  2598. .unwrap();
  2599. }
  2600. fn prologue() -> &'static str {
  2601. "
  2602. use compiler_builtins::int::udiv::__udivti3;
  2603. static TEST_CASES: &[((u128, u128), u128)] = &[
  2604. "
  2605. }
  2606. fn epilogue() -> &'static str {
  2607. "
  2608. ];
  2609. #[test]
  2610. fn udivti3() {
  2611. for &((a, b), c) in TEST_CASES {
  2612. let c_ = __udivti3(a, b);
  2613. assert_eq!(((a, b), c), ((a, b), c_));
  2614. }
  2615. }
  2616. "
  2617. }
  2618. }
  2619. #[derive(Eq, Hash, PartialEq)]
  2620. pub struct Umoddi3 {
  2621. a: u64,
  2622. b: u64,
  2623. c: u64,
  2624. }
  2625. impl TestCase for Umoddi3 {
  2626. fn name() -> &'static str {
  2627. "umoddi3"
  2628. }
  2629. fn generate<R>(rng: &mut R) -> Option<Self>
  2630. where
  2631. R: Rng,
  2632. Self: Sized,
  2633. {
  2634. let a = gen_u64(rng);
  2635. let b = gen_u64(rng);
  2636. if b == 0 {
  2637. return None;
  2638. }
  2639. let c = a % b;
  2640. Some(Umoddi3 { a, b, c })
  2641. }
  2642. fn to_string(&self, buffer: &mut String) {
  2643. writeln!(
  2644. buffer,
  2645. "(({a}, {b}), {c}),",
  2646. a = self.a,
  2647. b = self.b,
  2648. c = self.c
  2649. )
  2650. .unwrap();
  2651. }
  2652. fn prologue() -> &'static str {
  2653. "
  2654. use compiler_builtins::int::udiv::__umoddi3;
  2655. static TEST_CASES: &[((u64, u64), u64)] = &[
  2656. "
  2657. }
  2658. fn epilogue() -> &'static str {
  2659. "
  2660. ];
  2661. #[test]
  2662. fn umoddi3() {
  2663. for &((a, b), c) in TEST_CASES {
  2664. let c_ = __umoddi3(a, b);
  2665. assert_eq!(((a, b), c), ((a, b), c_));
  2666. }
  2667. }
  2668. "
  2669. }
  2670. }
  2671. #[derive(Eq, Hash, PartialEq)]
  2672. pub struct Umodsi3 {
  2673. a: u32,
  2674. b: u32,
  2675. c: u32,
  2676. }
  2677. impl TestCase for Umodsi3 {
  2678. fn name() -> &'static str {
  2679. "umodsi3"
  2680. }
  2681. fn generate<R>(rng: &mut R) -> Option<Self>
  2682. where
  2683. R: Rng,
  2684. Self: Sized,
  2685. {
  2686. let a = gen_u32(rng);
  2687. let b = gen_u32(rng);
  2688. if b == 0 {
  2689. return None;
  2690. }
  2691. let c = a % b;
  2692. Some(Umodsi3 { a, b, c })
  2693. }
  2694. fn to_string(&self, buffer: &mut String) {
  2695. writeln!(
  2696. buffer,
  2697. "(({a}, {b}), {c}),",
  2698. a = self.a,
  2699. b = self.b,
  2700. c = self.c
  2701. )
  2702. .unwrap();
  2703. }
  2704. fn prologue() -> &'static str {
  2705. "
  2706. use compiler_builtins::int::udiv::__umodsi3;
  2707. static TEST_CASES: &[((u32, u32), u32)] = &[
  2708. "
  2709. }
  2710. fn epilogue() -> &'static str {
  2711. "
  2712. ];
  2713. #[test]
  2714. fn umodsi3() {
  2715. for &((a, b), c) in TEST_CASES {
  2716. let c_ = __umodsi3(a, b);
  2717. assert_eq!(((a, b), c), ((a, b), c_));
  2718. }
  2719. }
  2720. "
  2721. }
  2722. }
  2723. #[derive(Eq, Hash, PartialEq)]
  2724. pub struct Umodti3 {
  2725. a: u128,
  2726. b: u128,
  2727. c: u128,
  2728. }
  2729. impl TestCase for Umodti3 {
  2730. fn name() -> &'static str {
  2731. "umodti3"
  2732. }
  2733. fn generate<R>(rng: &mut R) -> Option<Self>
  2734. where
  2735. R: Rng,
  2736. Self: Sized,
  2737. {
  2738. let a = gen_u128(rng);
  2739. let b = gen_u128(rng);
  2740. if b == 0 {
  2741. return None;
  2742. }
  2743. let c = a % b;
  2744. Some(Umodti3 { a, b, c })
  2745. }
  2746. fn to_string(&self, buffer: &mut String) {
  2747. writeln!(
  2748. buffer,
  2749. "(({a}, {b}), {c}),",
  2750. a = self.a,
  2751. b = self.b,
  2752. c = self.c
  2753. )
  2754. .unwrap();
  2755. }
  2756. fn prologue() -> &'static str {
  2757. "
  2758. use compiler_builtins::int::udiv::__umodti3;
  2759. static TEST_CASES: &[((u128, u128), u128)] = &[
  2760. "
  2761. }
  2762. fn epilogue() -> &'static str {
  2763. "
  2764. ];
  2765. #[test]
  2766. fn umodti3() {
  2767. for &((a, b), c) in TEST_CASES {
  2768. let c_ = __umodti3(a, b);
  2769. assert_eq!(((a, b), c), ((a, b), c_));
  2770. }
  2771. }
  2772. "
  2773. }
  2774. }
  2775. trait TestCase {
  2776. /// Name of the intrinsic to test
  2777. fn name() -> &'static str;
  2778. /// Generates a valid test case
  2779. fn generate<R>(rng: &mut R) -> Option<Self>
  2780. where
  2781. R: Rng,
  2782. Self: Sized;
  2783. /// Stringifies a test case
  2784. fn to_string(&self, buffer: &mut String);
  2785. /// Prologue of the test file
  2786. fn prologue() -> &'static str;
  2787. /// Epilogue of the test file
  2788. fn epilogue() -> &'static str;
  2789. }
  2790. const PROLOGUE: &'static str = r#"
  2791. extern crate compiler_builtins;
  2792. // test runner
  2793. #[cfg(all(target_arch = "arm",
  2794. not(any(target_env = "gnu", target_env = "musl")),
  2795. target_os = "linux",
  2796. test))]
  2797. extern crate utest_cortex_m_qemu;
  2798. // overrides `panic!`
  2799. #[cfg(all(target_arch = "arm",
  2800. not(any(target_env = "gnu", target_env = "musl")),
  2801. target_os = "linux",
  2802. test))]
  2803. #[macro_use]
  2804. extern crate utest_macros;
  2805. #[cfg(all(target_arch = "arm",
  2806. not(any(target_env = "gnu", target_env = "musl")),
  2807. target_os = "linux",
  2808. test))]
  2809. macro_rules! panic {
  2810. ($($tt:tt)*) => {
  2811. upanic!($($tt)*);
  2812. };
  2813. }
  2814. "#;
  2815. macro_rules! gen_int {
  2816. ($name:ident, $ity:ident, $hty:ident) => {
  2817. fn $name<R>(rng: &mut R) -> $ity
  2818. where
  2819. R: Rng,
  2820. {
  2821. let mut mk = || if rng.gen_weighted_bool(10) {
  2822. *rng.choose(&[::std::$hty::MAX, 0, ::std::$hty::MIN]).unwrap()
  2823. } else {
  2824. rng.gen::<$hty>()
  2825. };
  2826. unsafe { mem::transmute([mk(), mk()]) }
  2827. }
  2828. }
  2829. }
  2830. gen_int!(gen_i32, i32, i16);
  2831. gen_int!(gen_i64, i64, i32);
  2832. gen_int!(gen_i128, i128, i64);
  2833. macro_rules! gen_float {
  2834. ($name:ident,
  2835. $fty:ident,
  2836. $uty:ident,
  2837. $bits:expr,
  2838. $significand_bits:expr) => {
  2839. pub fn $name<R>(rng: &mut R) -> $fty
  2840. where
  2841. R: Rng,
  2842. {
  2843. const BITS: u8 = $bits;
  2844. const SIGNIFICAND_BITS: u8 = $significand_bits;
  2845. const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
  2846. const SIGN_MASK: $uty = (1 << (BITS - 1));
  2847. const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
  2848. fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
  2849. unsafe {
  2850. mem::transmute(((sign as $uty) << (BITS - 1)) |
  2851. ((exponent & EXPONENT_MASK) <<
  2852. SIGNIFICAND_BITS) |
  2853. (significand & SIGNIFICAND_MASK))
  2854. }
  2855. }
  2856. if rng.gen_weighted_bool(10) {
  2857. // Special values
  2858. *rng.choose(&[-0.0,
  2859. 0.0,
  2860. ::std::$fty::NAN,
  2861. ::std::$fty::INFINITY,
  2862. -::std::$fty::INFINITY])
  2863. .unwrap()
  2864. } else if rng.gen_weighted_bool(10) {
  2865. // NaN patterns
  2866. mk_f32(rng.gen(), rng.gen(), 0)
  2867. } else if rng.gen() {
  2868. // Denormalized
  2869. mk_f32(rng.gen(), 0, rng.gen())
  2870. } else {
  2871. // Random anything
  2872. mk_f32(rng.gen(), rng.gen(), rng.gen())
  2873. }
  2874. }
  2875. }
  2876. }
  2877. gen_float!(gen_f32, f32, u32, 32, 23);
  2878. gen_float!(gen_f64, f64, u64, 64, 52);
  2879. pub fn gen_u128<R>(rng: &mut R) -> u128
  2880. where
  2881. R: Rng,
  2882. {
  2883. gen_i128(rng) as u128
  2884. }
  2885. pub fn gen_u32<R>(rng: &mut R) -> u32
  2886. where
  2887. R: Rng,
  2888. {
  2889. gen_i32(rng) as u32
  2890. }
  2891. fn gen_u64<R>(rng: &mut R) -> u64
  2892. where
  2893. R: Rng,
  2894. {
  2895. gen_i64(rng) as u64
  2896. }
  2897. pub fn to_u32(x: f32) -> u32 {
  2898. unsafe { mem::transmute(x) }
  2899. }
  2900. pub fn to_u64(x: f64) -> u64 {
  2901. unsafe { mem::transmute(x) }
  2902. }
  2903. fn mk_tests<T, R>(mut n: usize, rng: &mut R) -> String
  2904. where
  2905. T: Eq + Hash + TestCase,
  2906. R: Rng,
  2907. {
  2908. let mut buffer = PROLOGUE.to_owned();
  2909. buffer.push_str(T::prologue());
  2910. let mut cases = HashSet::new();
  2911. while n != 0 {
  2912. if let Some(case) = T::generate(rng) {
  2913. if cases.contains(&case) {
  2914. continue;
  2915. }
  2916. case.to_string(&mut buffer);
  2917. n -= 1;
  2918. cases.insert(case);
  2919. }
  2920. }
  2921. buffer.push_str(T::epilogue());
  2922. buffer
  2923. }
  2924. fn mk_file<T>()
  2925. where
  2926. T: Eq + Hash + TestCase,
  2927. {
  2928. use std::io::Write;
  2929. let rng = &mut rand::thread_rng();
  2930. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  2931. let out_file = out_dir.join(format!("{}.rs", T::name()));
  2932. let contents = mk_tests::<T, _>(NTESTS, rng);
  2933. File::create(out_file)
  2934. .unwrap()
  2935. .write_all(contents.as_bytes())
  2936. .unwrap();
  2937. }
  2938. }
  2939. #[cfg(feature = "c")]
  2940. mod c {
  2941. extern crate gcc;
  2942. use std::collections::BTreeMap;
  2943. use std::env;
  2944. use std::path::Path;
  2945. struct Sources {
  2946. // SYMBOL -> PATH TO SOURCE
  2947. map: BTreeMap<&'static str, &'static str>,
  2948. }
  2949. impl Sources {
  2950. fn new() -> Sources {
  2951. Sources { map: BTreeMap::new() }
  2952. }
  2953. fn extend(&mut self, sources: &[&'static str]) {
  2954. // NOTE Some intrinsics have both a generic implementation (e.g.
  2955. // `floatdidf.c`) and an arch optimized implementation
  2956. // (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized
  2957. // implementation and discard the generic implementation. If we don't
  2958. // and keep both implementations, the linker will yell at us about
  2959. // duplicate symbols!
  2960. for &src in sources {
  2961. let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap();
  2962. if src.contains("/") {
  2963. // Arch-optimized implementation (preferred)
  2964. self.map.insert(symbol, src);
  2965. } else {
  2966. // Generic implementation
  2967. if !self.map.contains_key(symbol) {
  2968. self.map.insert(symbol, src);
  2969. }
  2970. }
  2971. }
  2972. }
  2973. fn remove(&mut self, symbols: &[&str]) {
  2974. for symbol in symbols {
  2975. self.map.remove(*symbol).unwrap();
  2976. }
  2977. }
  2978. }
  2979. /// Compile intrinsics from the compiler-rt C source code
  2980. pub fn compile(llvm_target: &[&str]) {
  2981. let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
  2982. let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
  2983. let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
  2984. let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
  2985. let cfg = &mut gcc::Config::new();
  2986. if target_env == "msvc" {
  2987. // Don't pull in extra libraries on MSVC
  2988. cfg.flag("/Zl");
  2989. // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
  2990. cfg.define("__func__", Some("__FUNCTION__"));
  2991. } else {
  2992. // Turn off various features of gcc and such, mostly copying
  2993. // compiler-rt's build system already
  2994. cfg.flag("-fno-builtin");
  2995. cfg.flag("-fvisibility=hidden");
  2996. cfg.flag("-fomit-frame-pointer");
  2997. cfg.flag("-ffreestanding");
  2998. cfg.define("VISIBILITY_HIDDEN", None);
  2999. }
  3000. // NOTE Most of the ARM intrinsics are written in assembly. Tell gcc which arch we are going
  3001. // to target to make sure that the assembly implementations really work for the target. If
  3002. // the implementation is not valid for the arch, then gcc will error when compiling it.
  3003. if llvm_target[0].starts_with("thumb") {
  3004. cfg.flag("-mthumb");
  3005. if llvm_target.last() == Some(&"eabihf") {
  3006. cfg.flag("-mfloat-abi=hard");
  3007. }
  3008. }
  3009. if llvm_target[0] == "thumbv6m" {
  3010. cfg.flag("-march=armv6-m");
  3011. }
  3012. if llvm_target[0] == "thumbv7m" {
  3013. cfg.flag("-march=armv7-m");
  3014. }
  3015. if llvm_target[0] == "thumbv7em" {
  3016. cfg.flag("-march=armv7e-m");
  3017. }
  3018. let mut sources = Sources::new();
  3019. sources.extend(
  3020. &[
  3021. "absvdi2.c",
  3022. "absvsi2.c",
  3023. "addvdi3.c",
  3024. "addvsi3.c",
  3025. "apple_versioning.c",
  3026. "clzdi2.c",
  3027. "clzsi2.c",
  3028. "cmpdi2.c",
  3029. "comparedf2.c",
  3030. "comparesf2.c",
  3031. "ctzdi2.c",
  3032. "ctzsi2.c",
  3033. "divdc3.c",
  3034. "divdf3.c",
  3035. "divsc3.c",
  3036. "divsf3.c",
  3037. "divxc3.c",
  3038. "extendsfdf2.c",
  3039. "extendhfsf2.c",
  3040. "ffsdi2.c",
  3041. "fixdfdi.c",
  3042. "fixdfsi.c",
  3043. "fixsfdi.c",
  3044. "fixsfsi.c",
  3045. "fixunsdfdi.c",
  3046. "fixunsdfsi.c",
  3047. "fixunssfdi.c",
  3048. "fixunssfsi.c",
  3049. "fixunsxfdi.c",
  3050. "fixunsxfsi.c",
  3051. "fixxfdi.c",
  3052. "floatdidf.c",
  3053. "floatdisf.c",
  3054. "floatdixf.c",
  3055. "floatsidf.c",
  3056. "floatsisf.c",
  3057. "floatundidf.c",
  3058. "floatundisf.c",
  3059. "floatundixf.c",
  3060. "floatunsidf.c",
  3061. "floatunsisf.c",
  3062. "int_util.c",
  3063. "muldc3.c",
  3064. "muldf3.c",
  3065. "mulsc3.c",
  3066. "mulsf3.c",
  3067. "mulvdi3.c",
  3068. "mulvsi3.c",
  3069. "mulxc3.c",
  3070. "negdf2.c",
  3071. "negdi2.c",
  3072. "negsf2.c",
  3073. "negvdi2.c",
  3074. "negvsi2.c",
  3075. "paritydi2.c",
  3076. "paritysi2.c",
  3077. "popcountdi2.c",
  3078. "popcountsi2.c",
  3079. "powixf2.c",
  3080. "subvdi3.c",
  3081. "subvsi3.c",
  3082. "truncdfhf2.c",
  3083. "truncdfsf2.c",
  3084. "truncsfhf2.c",
  3085. "ucmpdi2.c",
  3086. ],
  3087. );
  3088. if target_os != "ios" {
  3089. sources.extend(
  3090. &[
  3091. "absvti2.c",
  3092. "addvti3.c",
  3093. "clzti2.c",
  3094. "cmpti2.c",
  3095. "ctzti2.c",
  3096. "ffsti2.c",
  3097. "fixdfti.c",
  3098. "fixsfti.c",
  3099. "fixunsdfti.c",
  3100. "fixunssfti.c",
  3101. "fixunsxfti.c",
  3102. "fixxfti.c",
  3103. "floattidf.c",
  3104. "floattisf.c",
  3105. "floattixf.c",
  3106. "floatuntidf.c",
  3107. "floatuntisf.c",
  3108. "floatuntixf.c",
  3109. "mulvti3.c",
  3110. "negti2.c",
  3111. "negvti2.c",
  3112. "parityti2.c",
  3113. "popcountti2.c",
  3114. "subvti3.c",
  3115. "ucmpti2.c",
  3116. ],
  3117. );
  3118. }
  3119. if target_vendor == "apple" {
  3120. sources.extend(
  3121. &[
  3122. "atomic_flag_clear.c",
  3123. "atomic_flag_clear_explicit.c",
  3124. "atomic_flag_test_and_set.c",
  3125. "atomic_flag_test_and_set_explicit.c",
  3126. "atomic_signal_fence.c",
  3127. "atomic_thread_fence.c",
  3128. ],
  3129. );
  3130. }
  3131. if target_env == "msvc" {
  3132. if target_arch == "x86_64" {
  3133. sources.extend(
  3134. &[
  3135. "x86_64/floatdidf.c",
  3136. "x86_64/floatdisf.c",
  3137. "x86_64/floatdixf.c",
  3138. ],
  3139. );
  3140. }
  3141. } else {
  3142. if target_os != "freebsd" && target_os != "netbsd" {
  3143. sources.extend(&["gcc_personality_v0.c"]);
  3144. }
  3145. if target_arch == "x86_64" {
  3146. sources.extend(
  3147. &[
  3148. "x86_64/chkstk.S",
  3149. "x86_64/chkstk2.S",
  3150. "x86_64/floatdidf.c",
  3151. "x86_64/floatdisf.c",
  3152. "x86_64/floatdixf.c",
  3153. "x86_64/floatundidf.S",
  3154. "x86_64/floatundisf.S",
  3155. "x86_64/floatundixf.S",
  3156. ],
  3157. );
  3158. }
  3159. if target_arch == "x86" {
  3160. sources.extend(
  3161. &[
  3162. "i386/ashldi3.S",
  3163. "i386/ashrdi3.S",
  3164. "i386/chkstk.S",
  3165. "i386/chkstk2.S",
  3166. "i386/divdi3.S",
  3167. "i386/floatdidf.S",
  3168. "i386/floatdisf.S",
  3169. "i386/floatdixf.S",
  3170. "i386/floatundidf.S",
  3171. "i386/floatundisf.S",
  3172. "i386/floatundixf.S",
  3173. "i386/lshrdi3.S",
  3174. "i386/moddi3.S",
  3175. "i386/muldi3.S",
  3176. "i386/udivdi3.S",
  3177. "i386/umoddi3.S",
  3178. ],
  3179. );
  3180. }
  3181. }
  3182. if target_arch == "arm" && target_os != "ios" {
  3183. sources.extend(
  3184. &[
  3185. "arm/aeabi_cdcmp.S",
  3186. "arm/aeabi_cdcmpeq_check_nan.c",
  3187. "arm/aeabi_cfcmp.S",
  3188. "arm/aeabi_cfcmpeq_check_nan.c",
  3189. "arm/aeabi_dcmp.S",
  3190. "arm/aeabi_div0.c",
  3191. "arm/aeabi_drsub.c",
  3192. "arm/aeabi_fcmp.S",
  3193. "arm/aeabi_frsub.c",
  3194. "arm/bswapdi2.S",
  3195. "arm/bswapsi2.S",
  3196. "arm/clzdi2.S",
  3197. "arm/clzsi2.S",
  3198. "arm/comparesf2.S",
  3199. "arm/divmodsi4.S",
  3200. "arm/divsi3.S",
  3201. "arm/modsi3.S",
  3202. "arm/switch16.S",
  3203. "arm/switch32.S",
  3204. "arm/switch8.S",
  3205. "arm/switchu8.S",
  3206. "arm/sync_synchronize.S",
  3207. "arm/udivmodsi4.S",
  3208. "arm/udivsi3.S",
  3209. "arm/umodsi3.S",
  3210. ],
  3211. );
  3212. }
  3213. if llvm_target[0] == "armv7" {
  3214. sources.extend(
  3215. &[
  3216. "arm/sync_fetch_and_add_4.S",
  3217. "arm/sync_fetch_and_add_8.S",
  3218. "arm/sync_fetch_and_and_4.S",
  3219. "arm/sync_fetch_and_and_8.S",
  3220. "arm/sync_fetch_and_max_4.S",
  3221. "arm/sync_fetch_and_max_8.S",
  3222. "arm/sync_fetch_and_min_4.S",
  3223. "arm/sync_fetch_and_min_8.S",
  3224. "arm/sync_fetch_and_nand_4.S",
  3225. "arm/sync_fetch_and_nand_8.S",
  3226. "arm/sync_fetch_and_or_4.S",
  3227. "arm/sync_fetch_and_or_8.S",
  3228. "arm/sync_fetch_and_sub_4.S",
  3229. "arm/sync_fetch_and_sub_8.S",
  3230. "arm/sync_fetch_and_umax_4.S",
  3231. "arm/sync_fetch_and_umax_8.S",
  3232. "arm/sync_fetch_and_umin_4.S",
  3233. "arm/sync_fetch_and_umin_8.S",
  3234. "arm/sync_fetch_and_xor_4.S",
  3235. "arm/sync_fetch_and_xor_8.S",
  3236. ],
  3237. );
  3238. }
  3239. if llvm_target.last().unwrap().ends_with("eabihf") {
  3240. if !llvm_target[0].starts_with("thumbv7em") {
  3241. sources.extend(
  3242. &[
  3243. "arm/adddf3vfp.S",
  3244. "arm/addsf3vfp.S",
  3245. "arm/divdf3vfp.S",
  3246. "arm/divsf3vfp.S",
  3247. "arm/eqdf2vfp.S",
  3248. "arm/eqsf2vfp.S",
  3249. "arm/extendsfdf2vfp.S",
  3250. "arm/fixdfsivfp.S",
  3251. "arm/fixsfsivfp.S",
  3252. "arm/fixunsdfsivfp.S",
  3253. "arm/fixunssfsivfp.S",
  3254. "arm/floatsidfvfp.S",
  3255. "arm/floatsisfvfp.S",
  3256. "arm/floatunssidfvfp.S",
  3257. "arm/floatunssisfvfp.S",
  3258. "arm/gedf2vfp.S",
  3259. "arm/gesf2vfp.S",
  3260. "arm/gtdf2vfp.S",
  3261. "arm/gtsf2vfp.S",
  3262. "arm/ledf2vfp.S",
  3263. "arm/lesf2vfp.S",
  3264. "arm/ltdf2vfp.S",
  3265. "arm/ltsf2vfp.S",
  3266. "arm/muldf3vfp.S",
  3267. "arm/mulsf3vfp.S",
  3268. "arm/nedf2vfp.S",
  3269. "arm/nesf2vfp.S",
  3270. "arm/restore_vfp_d8_d15_regs.S",
  3271. "arm/save_vfp_d8_d15_regs.S",
  3272. "arm/subdf3vfp.S",
  3273. "arm/subsf3vfp.S",
  3274. ],
  3275. );
  3276. }
  3277. sources.extend(&["arm/negdf2vfp.S", "arm/negsf2vfp.S"]);
  3278. }
  3279. if target_arch == "aarch64" {
  3280. sources.extend(
  3281. &[
  3282. "comparetf2.c",
  3283. "extenddftf2.c",
  3284. "extendsftf2.c",
  3285. "fixtfdi.c",
  3286. "fixtfsi.c",
  3287. "fixtfti.c",
  3288. "fixunstfdi.c",
  3289. "fixunstfsi.c",
  3290. "fixunstfti.c",
  3291. "floatditf.c",
  3292. "floatsitf.c",
  3293. "floatunditf.c",
  3294. "floatunsitf.c",
  3295. "multc3.c",
  3296. "trunctfdf2.c",
  3297. "trunctfsf2.c",
  3298. ],
  3299. );
  3300. }
  3301. // Remove the assembly implementations that won't compile for the target
  3302. if llvm_target[0] == "thumbv6m" {
  3303. sources.remove(
  3304. &[
  3305. "aeabi_cdcmp",
  3306. "aeabi_cfcmp",
  3307. "aeabi_dcmp",
  3308. "aeabi_fcmp",
  3309. "clzdi2",
  3310. "clzsi2",
  3311. "comparesf2",
  3312. "divmodsi4",
  3313. "divsi3",
  3314. "modsi3",
  3315. "switch16",
  3316. "switch32",
  3317. "switch8",
  3318. "switchu8",
  3319. "udivmodsi4",
  3320. "udivsi3",
  3321. "umodsi3",
  3322. ],
  3323. );
  3324. // But use some generic implementations where possible
  3325. sources.extend(&["clzdi2.c", "clzsi2.c"])
  3326. }
  3327. if llvm_target[0] == "thumbv7m" || llvm_target[0] == "thumbv7em" {
  3328. sources.remove(&["aeabi_cdcmp", "aeabi_cfcmp"]);
  3329. }
  3330. let root = if env::var_os("CARGO_FEATURE_RUSTBUILD").is_some() {
  3331. Path::new("../../libcompiler_builtins")
  3332. } else {
  3333. Path::new(".")
  3334. };
  3335. let src_dir = root.join("compiler-rt/lib/builtins");
  3336. for src in sources.map.values() {
  3337. let src = src_dir.join(src);
  3338. cfg.file(&src);
  3339. println!("cargo:rerun-if-changed={}", src.display());
  3340. }
  3341. cfg.compile("libcompiler-rt.a");
  3342. }
  3343. }