12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978 |
- #![feature(i128_type)]
- use std::env;
- fn main() {
- println!("cargo:rerun-if-changed=build.rs");
- let target = env::var("TARGET").unwrap();
- // Emscripten's runtime includes all the builtins
- if target.contains("emscripten") {
- return;
- }
- // NOTE we are going to assume that llvm-target, what determines our codegen option, matches the
- // target triple. This is usually correct for our built-in targets but can break in presence of
- // custom targets, which can have arbitrary names.
- let llvm_target = target.split('-').collect::<Vec<_>>();
- // Build test files
- tests::generate();
- // Build missing intrinsics from compiler-rt C source code
- #[cfg(feature = "c")]
- c::compile(&llvm_target);
- // To compile intrinsics.rs for thumb targets, where there is no libc
- if llvm_target[0].starts_with("thumb") {
- println!("cargo:rustc-cfg=thumb")
- }
- // compiler-rt `cfg`s away some intrinsics for thumbv6m because that target doesn't have full
- // THUMBv2 support. We have to cfg our code accordingly.
- if llvm_target[0] == "thumbv6m" {
- println!("cargo:rustc-cfg=thumbv6m")
- }
- }
- mod tests {
- extern crate rand;
- use std::collections::HashSet;
- use std::fmt::Write;
- use std::fs::File;
- use std::hash::Hash;
- use std::path::PathBuf;
- use std::{env, mem};
- use self::rand::Rng;
- const NTESTS: usize = 10_000;
- macro_rules! test {
- ($($intrinsic:ident,)+) => {
- $(
- mk_file::<$intrinsic>();
- )+
- }
- }
- pub fn generate() {
- // TODO move to main
- test! {
- // float/add.rs
- Adddf3,
- Addsf3,
- // float/conv.rs
- // Fixdfdi,
- // Fixdfsi,
- // Fixsfdi,
- // Fixsfsi,
- // Fixunsdfdi,
- // Fixunsdfsi,
- // Fixunssfdi,
- // Fixunssfsi,
- // Floatdidf,
- // Floatsidf,
- // Floatsisf,
- // Floatundidf,
- // Floatunsidf,
- // Floatunsisf,
- // float/pow.rs
- Powidf2,
- Powisf2,
- // float/sub.rs
- Subdf3,
- Subsf3,
- // int/mul.rs
- Muldi3,
- Mulodi4,
- Mulosi4,
- Muloti4,
- Multi3,
- // int/sdiv.rs
- Divdi3,
- Divmoddi4,
- Divmodsi4,
- Divsi3,
- Divti3,
- Moddi3,
- Modsi3,
- Modti3,
- // int/shift.rs
- Ashldi3,
- Ashlti3,
- Ashrdi3,
- Ashrti3,
- Lshrdi3,
- Lshrti3,
- // int/udiv.rs
- Udivdi3,
- Udivmoddi4,
- Udivmodsi4,
- Udivmodti4,
- Udivsi3,
- Udivti3,
- Umoddi3,
- Umodsi3,
- Umodti3,
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Adddf3 {
- a: u64,
- b: u64,
- c: u64,
- }
- impl TestCase for Adddf3 {
- fn name() -> &'static str {
- "adddf3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_f64(rng);
- let b = gen_f64(rng);
- let c = a + b;
- // TODO accept NaNs. We don't do that right now because we can't check
- // for NaN-ness on the thumb targets (due to missing intrinsics)
- if a.is_nan() || b.is_nan() || c.is_nan() {
- return None;
- }
- Some(
- Adddf3 {
- a: to_u64(a),
- b: to_u64(b),
- c: to_u64(c),
- },
- )
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- r#"
- #[cfg(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test))]
- use core::mem;
- #[cfg(not(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test)))]
- use std::mem;
- use compiler_builtins::float::add::__adddf3;
- fn mk_f64(x: u64) -> f64 {
- unsafe { mem::transmute(x) }
- }
- fn to_u64(x: f64) -> u64 {
- unsafe { mem::transmute(x) }
- }
- static TEST_CASES: &[((u64, u64), u64)] = &[
- "#
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn adddf3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __adddf3(mk_f64(a), mk_f64(b));
- assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Addsf3 {
- a: u32,
- b: u32,
- c: u32,
- }
- impl TestCase for Addsf3 {
- fn name() -> &'static str {
- "addsf3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_f32(rng);
- let b = gen_f32(rng);
- let c = a + b;
- // TODO accept NaNs. We don't do that right now because we can't check
- // for NaN-ness on the thumb targets (due to missing intrinsics)
- if a.is_nan() || b.is_nan() || c.is_nan() {
- return None;
- }
- Some(
- Addsf3 {
- a: to_u32(a),
- b: to_u32(b),
- c: to_u32(c),
- },
- )
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- r#"
- #[cfg(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test))]
- use core::mem;
- #[cfg(not(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test)))]
- use std::mem;
- use compiler_builtins::float::add::__addsf3;
- fn mk_f32(x: u32) -> f32 {
- unsafe { mem::transmute(x) }
- }
- fn to_u32(x: f32) -> u32 {
- unsafe { mem::transmute(x) }
- }
- static TEST_CASES: &[((u32, u32), u32)] = &[
- "#
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn addsf3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __addsf3(mk_f32(a), mk_f32(b));
- assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Ashldi3 {
- a: u64,
- b: u32,
- c: u64,
- }
- impl TestCase for Ashldi3 {
- fn name() -> &'static str {
- "ashldi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u64(rng);
- let b = (rng.gen::<u8>() % 64) as u32;
- let c = a << b;
- Some(Ashldi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::shift::__ashldi3;
- static TEST_CASES: &[((u64, u32), u64)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn ashldi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __ashldi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Ashlti3 {
- a: u128,
- b: u32,
- c: u128,
- }
- impl TestCase for Ashlti3 {
- fn name() -> &'static str {
- "ashlti3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u128(rng);
- let b = (rng.gen::<u8>() % 128) as u32;
- let c = a << b;
- Some(Ashlti3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::shift::__ashlti3;
- static TEST_CASES: &[((u128, u32), u128)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn ashlti3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __ashlti3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Ashrdi3 {
- a: i64,
- b: u32,
- c: i64,
- }
- impl TestCase for Ashrdi3 {
- fn name() -> &'static str {
- "ashrdi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i64(rng);
- let b = (rng.gen::<u8>() % 64) as u32;
- let c = a >> b;
- Some(Ashrdi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::shift::__ashrdi3;
- static TEST_CASES: &[((i64, u32), i64)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn ashrdi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __ashrdi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Ashrti3 {
- a: i128,
- b: u32,
- c: i128,
- }
- impl TestCase for Ashrti3 {
- fn name() -> &'static str {
- "ashrti3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i128(rng);
- let b = (rng.gen::<u8>() % 128) as u32;
- let c = a >> b;
- Some(Ashrti3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::shift::__ashrti3;
- static TEST_CASES: &[((i128, u32), i128)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn ashrti3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __ashrti3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Divmoddi4 {
- a: i64,
- b: i64,
- c: i64,
- rem: i64,
- }
- impl TestCase for Divmoddi4 {
- fn name() -> &'static str {
- "divmoddi4"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i64(rng);
- let b = gen_i64(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- let rem = a % b;
- Some(Divmoddi4 { a, b, c, rem })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), ({c}, {rem})),",
- a = self.a,
- b = self.b,
- c = self.c,
- rem = self.rem
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::sdiv::__divmoddi4;
- static TEST_CASES: &[((i64, i64), (i64, i64))] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn divmoddi4() {
- for &((a, b), (c, rem)) in TEST_CASES {
- let mut rem_ = 0;
- let c_ = __divmoddi4(a, b, &mut rem_);
- assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Divdi3 {
- a: i64,
- b: i64,
- c: i64,
- }
- impl TestCase for Divdi3 {
- fn name() -> &'static str {
- "divdi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i64(rng);
- let b = gen_i64(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- Some(Divdi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::sdiv::__divdi3;
- static TEST_CASES: &[((i64, i64), i64)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn divdi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __divdi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Divmodsi4 {
- a: i32,
- b: i32,
- c: i32,
- rem: i32,
- }
- impl TestCase for Divmodsi4 {
- fn name() -> &'static str {
- "divmodsi4"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i32(rng);
- let b = gen_i32(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- let rem = a % b;
- Some(Divmodsi4 { a, b, c, rem })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), ({c}, {rem})),",
- a = self.a,
- b = self.b,
- c = self.c,
- rem = self.rem
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::sdiv::__divmodsi4;
- static TEST_CASES: &[((i32, i32), (i32, i32))] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn divmodsi4() {
- for &((a, b), (c, rem)) in TEST_CASES {
- let mut rem_ = 0;
- let c_ = __divmodsi4(a, b, &mut rem_);
- assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Divsi3 {
- a: i32,
- b: i32,
- c: i32,
- }
- impl TestCase for Divsi3 {
- fn name() -> &'static str {
- "divsi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i32(rng);
- let b = gen_i32(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- Some(Divsi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::sdiv::__divsi3;
- static TEST_CASES: &[((i32, i32), i32)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn divsi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __divsi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Divti3 {
- a: i128,
- b: i128,
- c: i128,
- }
- impl TestCase for Divti3 {
- fn name() -> &'static str {
- "divti3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i128(rng);
- let b = gen_i128(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- Some(Divti3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::sdiv::__divti3;
- static TEST_CASES: &[((i128, i128), i128)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn divti3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __divti3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Moddi3 {
- a: i64,
- b: i64,
- c: i64,
- }
- impl TestCase for Moddi3 {
- fn name() -> &'static str {
- "moddi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i64(rng);
- let b = gen_i64(rng);
- if b == 0 {
- return None;
- }
- let c = a % b;
- Some(Moddi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::sdiv::__moddi3;
- static TEST_CASES: &[((i64, i64), i64)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn moddi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __moddi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Modsi3 {
- a: i32,
- b: i32,
- c: i32,
- }
- impl TestCase for Modsi3 {
- fn name() -> &'static str {
- "modsi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i32(rng);
- let b = gen_i32(rng);
- if b == 0 {
- return None;
- }
- let c = a % b;
- Some(Modsi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::sdiv::__modsi3;
- static TEST_CASES: &[((i32, i32), i32)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn modsi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __modsi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Modti3 {
- a: i128,
- b: i128,
- c: i128,
- }
- impl TestCase for Modti3 {
- fn name() -> &'static str {
- "modti3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i128(rng);
- let b = gen_i128(rng);
- if b == 0 {
- return None;
- }
- let c = a % b;
- Some(Modti3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::sdiv::__modti3;
- static TEST_CASES: &[((i128, i128), i128)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn modti3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __modti3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- struct Muldi3 {
- a: u64,
- b: u64,
- c: u64,
- }
- impl TestCase for Muldi3 {
- fn name() -> &'static str {
- "muldi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u64(rng);
- let b = gen_u64(rng);
- let c = a.wrapping_mul(b);
- Some(Muldi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::mul::__muldi3;
- static TEST_CASES: &[((u64, u64), u64)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn muldi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __muldi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Mulodi4 {
- a: i64,
- b: i64,
- c: i64,
- overflow: u32,
- }
- impl TestCase for Mulodi4 {
- fn name() -> &'static str {
- "mulodi4"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- {
- let a = gen_i64(rng);
- let b = gen_i64(rng);
- let c = a.wrapping_mul(b);
- let overflow = if a.checked_mul(b).is_some() { 0 } else { 1 };
- Some(Mulodi4 { a, b, c, overflow })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), ({c}, {overflow})),",
- a = self.a,
- b = self.b,
- c = self.c,
- overflow = self.overflow
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::mul::__mulodi4;
- static TEST_CASES: &[((i64, i64), (i64, i32))] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn mulodi4() {
- let mut overflow_ = 2;
- for &((a, b), (c, overflow)) in TEST_CASES {
- let c_ = __mulodi4(a, b, &mut overflow_);
- assert_eq!(((a, b), (c, overflow)), ((a, b), (c_, overflow_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Mulosi4 {
- a: i32,
- b: i32,
- c: i32,
- overflow: u32,
- }
- impl TestCase for Mulosi4 {
- fn name() -> &'static str {
- "mulosi4"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- {
- let a = gen_i32(rng);
- let b = gen_i32(rng);
- let c = a.wrapping_mul(b);
- let overflow = if a.checked_mul(b).is_some() { 0 } else { 1 };
- Some(Mulosi4 { a, b, c, overflow })
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::mul::__mulosi4;
- static TEST_CASES: &[((i32, i32), (i32, i32))] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn mulosi4() {
- let mut overflow_ = 2;
- for &((a, b), (c, overflow)) in TEST_CASES {
- let c_ = __mulosi4(a, b, &mut overflow_);
- assert_eq!(((a, b), (c, overflow)), ((a, b), (c_, overflow_)));
- }
- }
- "
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), ({c}, {overflow})),",
- a = self.a,
- b = self.b,
- c = self.c,
- overflow = self.overflow
- )
- .unwrap();
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Muloti4 {
- a: i128,
- b: i128,
- c: i128,
- overflow: u32,
- }
- impl TestCase for Muloti4 {
- fn name() -> &'static str {
- "muloti4"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- {
- let a = gen_i128(rng);
- let b = gen_i128(rng);
- let c = a.wrapping_mul(b);
- let overflow = if a.checked_mul(b).is_some() { 0 } else { 1 };
- Some(Muloti4 { a, b, c, overflow })
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::mul::__muloti4;
- static TEST_CASES: &[((i128, i128), (i128, i32))] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn muloti4() {
- let mut overflow_ = 2;
- for &((a, b), (c, overflow)) in TEST_CASES {
- let c_ = __muloti4(a, b, &mut overflow_);
- assert_eq!(((a, b), (c, overflow)), ((a, b), (c_, overflow_)));
- }
- }
- "
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), ({c}, {overflow})),",
- a = self.a,
- b = self.b,
- c = self.c,
- overflow = self.overflow
- )
- .unwrap();
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Multi3 {
- a: i128,
- b: i128,
- c: i128,
- }
- impl TestCase for Multi3 {
- fn name() -> &'static str {
- "multi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_i128(rng);
- let b = gen_i128(rng);
- let c = a.wrapping_mul(b);
- Some(Multi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::mul::__multi3;
- static TEST_CASES: &[((i128, i128), i128)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn multi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __multi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Powidf2 {
- a: u64,
- b: i32,
- c: u64,
- }
- impl TestCase for Powidf2 {
- fn name() -> &'static str {
- "powidf2"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_f64(rng);
- let b = gen_i32(rng);
- let c = a.powi(b);
- // TODO accept NaNs. We don't do that right now because we can't check
- // for NaN-ness on the thumb targets
- if a.is_nan() || c.is_nan() {
- return None;
- }
- Some(
- Powidf2 {
- a: to_u64(a),
- b,
- c: to_u64(c),
- },
- )
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- r#"
- #[cfg(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test))]
- use core::mem;
- #[cfg(not(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test)))]
- use std::mem;
- use compiler_builtins::float::pow::__powidf2;
- fn mk_f64(x: u64) -> f64 {
- unsafe { mem::transmute(x) }
- }
- fn to_u64(x: f64) -> u64 {
- unsafe { mem::transmute(x) }
- }
- static TEST_CASES: &[((u64, i32), u64)] = &[
- "#
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn powidf2() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __powidf2(mk_f64(a), b);
- assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Powisf2 {
- a: u32,
- b: i32,
- c: u32,
- }
- impl TestCase for Powisf2 {
- fn name() -> &'static str {
- "powisf2"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_f32(rng);
- let b = gen_i32(rng);
- let c = a.powi(b);
- // TODO accept NaNs. We don't do that right now because we can't check
- // for NaN-ness on the thumb targets
- if a.is_nan() || c.is_nan() {
- return None;
- }
- Some(
- Powisf2 {
- a: to_u32(a),
- b,
- c: to_u32(c),
- },
- )
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- r#"
- #[cfg(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test))]
- use core::mem;
- #[cfg(not(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test)))]
- use std::mem;
- use compiler_builtins::float::pow::__powisf2;
- fn mk_f32(x: u32) -> f32 {
- unsafe { mem::transmute(x) }
- }
- fn to_u32(x: f32) -> u32 {
- unsafe { mem::transmute(x) }
- }
- static TEST_CASES: &[((u32, i32), u32)] = &[
- "#
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn powisf2() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __powisf2(mk_f32(a), b);
- assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Lshrdi3 {
- a: u64,
- b: u32,
- c: u64,
- }
- impl TestCase for Lshrdi3 {
- fn name() -> &'static str {
- "lshrdi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u64(rng);
- let b = (rng.gen::<u8>() % 64) as u32;
- let c = a >> b;
- Some(Lshrdi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::shift::__lshrdi3;
- static TEST_CASES: &[((u64, u32), u64)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn lshrdi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __lshrdi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Lshrti3 {
- a: u128,
- b: u32,
- c: u128,
- }
- impl TestCase for Lshrti3 {
- fn name() -> &'static str {
- "lshrti3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u128(rng);
- let b = (rng.gen::<u8>() % 128) as u32;
- let c = a >> b;
- Some(Lshrti3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::shift::__lshrti3;
- static TEST_CASES: &[((u128, u32), u128)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn lshrti3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __lshrti3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Subdf3 {
- a: u64,
- b: u64,
- c: u64,
- }
- impl TestCase for Subdf3 {
- fn name() -> &'static str {
- "subdf3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_f64(rng);
- let b = gen_f64(rng);
- let c = a - b;
- // TODO accept NaNs. We don't do that right now because we can't check
- // for NaN-ness on the thumb targets (due to missing intrinsics)
- if a.is_nan() || b.is_nan() || c.is_nan() {
- return None;
- }
- Some(
- Subdf3 {
- a: to_u64(a),
- b: to_u64(b),
- c: to_u64(c),
- },
- )
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- r#"
- #[cfg(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test))]
- use core::mem;
- #[cfg(not(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test)))]
- use std::mem;
- use compiler_builtins::float::sub::__subdf3;
- fn mk_f64(x: u64) -> f64 {
- unsafe { mem::transmute(x) }
- }
- fn to_u64(x: f64) -> u64 {
- unsafe { mem::transmute(x) }
- }
- static TEST_CASES: &[((u64, u64), u64)] = &[
- "#
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn subdf3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __subdf3(mk_f64(a), mk_f64(b));
- assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Subsf3 {
- a: u32,
- b: u32,
- c: u32,
- }
- impl TestCase for Subsf3 {
- fn name() -> &'static str {
- "subsf3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_f32(rng);
- let b = gen_f32(rng);
- let c = a - b;
- // TODO accept NaNs. We don't do that right now because we can't check
- // for NaN-ness on the thumb targets (due to missing intrinsics)
- if a.is_nan() || b.is_nan() || c.is_nan() {
- return None;
- }
- Some(
- Subsf3 {
- a: to_u32(a),
- b: to_u32(b),
- c: to_u32(c),
- },
- )
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- r#"
- #[cfg(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test))]
- use core::mem;
- #[cfg(not(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test)))]
- use std::mem;
- use compiler_builtins::float::sub::__subsf3;
- fn mk_f32(x: u32) -> f32 {
- unsafe { mem::transmute(x) }
- }
- fn to_u32(x: f32) -> u32 {
- unsafe { mem::transmute(x) }
- }
- static TEST_CASES: &[((u32, u32), u32)] = &[
- "#
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn subsf3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __subsf3(mk_f32(a), mk_f32(b));
- assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Udivdi3 {
- a: u64,
- b: u64,
- c: u64,
- }
- impl TestCase for Udivdi3 {
- fn name() -> &'static str {
- "udivdi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u64(rng);
- let b = gen_u64(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- Some(Udivdi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::udiv::__udivdi3;
- static TEST_CASES: &[((u64, u64), u64)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn udivdi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __udivdi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Udivmoddi4 {
- a: u64,
- b: u64,
- c: u64,
- rem: u64,
- }
- impl TestCase for Udivmoddi4 {
- fn name() -> &'static str {
- "udivmoddi4"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u64(rng);
- let b = gen_u64(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- let rem = a % b;
- Some(Udivmoddi4 { a, b, c, rem })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), ({c}, {rem})),",
- a = self.a,
- b = self.b,
- c = self.c,
- rem = self.rem
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::udiv::__udivmoddi4;
- static TEST_CASES: &[((u64, u64), (u64, u64))] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn udivmoddi4() {
- for &((a, b), (c, rem)) in TEST_CASES {
- let mut rem_ = 0;
- let c_ = __udivmoddi4(a, b, Some(&mut rem_));
- assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Udivmodsi4 {
- a: u32,
- b: u32,
- c: u32,
- rem: u32,
- }
- impl TestCase for Udivmodsi4 {
- fn name() -> &'static str {
- "udivmodsi4"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u32(rng);
- let b = gen_u32(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- let rem = a % b;
- Some(Udivmodsi4 { a, b, c, rem })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), ({c}, {rem})),",
- a = self.a,
- b = self.b,
- c = self.c,
- rem = self.rem
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::udiv::__udivmodsi4;
- static TEST_CASES: &[((u32, u32), (u32, u32))] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn udivmodsi4() {
- for &((a, b), (c, rem)) in TEST_CASES {
- let mut rem_ = 0;
- let c_ = __udivmodsi4(a, b, Some(&mut rem_));
- assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Udivmodti4 {
- a: u128,
- b: u128,
- c: u128,
- rem: u128,
- }
- impl TestCase for Udivmodti4 {
- fn name() -> &'static str {
- "udivmodti4"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u128(rng);
- let b = gen_u128(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- let rem = a % b;
- Some(Udivmodti4 { a, b, c, rem })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), ({c}, {rem})),",
- a = self.a,
- b = self.b,
- c = self.c,
- rem = self.rem
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::udiv::__udivmodti4;
- static TEST_CASES: &[((u128, u128), (u128, u128))] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn udivmodti4() {
- for &((a, b), (c, rem)) in TEST_CASES {
- let mut rem_ = 0;
- let c_ = __udivmodti4(a, b, Some(&mut rem_));
- assert_eq!(((a, b), (c, rem)), ((a, b), (c_, rem_)));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Udivsi3 {
- a: u32,
- b: u32,
- c: u32,
- }
- impl TestCase for Udivsi3 {
- fn name() -> &'static str {
- "udivsi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u32(rng);
- let b = gen_u32(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- Some(Udivsi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::udiv::__udivsi3;
- static TEST_CASES: &[((u32, u32), u32)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn udivsi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __udivsi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Udivti3 {
- a: u128,
- b: u128,
- c: u128,
- }
- impl TestCase for Udivti3 {
- fn name() -> &'static str {
- "udivti3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u128(rng);
- let b = gen_u128(rng);
- if b == 0 {
- return None;
- }
- let c = a / b;
- Some(Udivti3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::udiv::__udivti3;
- static TEST_CASES: &[((u128, u128), u128)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn udivti3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __udivti3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Umoddi3 {
- a: u64,
- b: u64,
- c: u64,
- }
- impl TestCase for Umoddi3 {
- fn name() -> &'static str {
- "umoddi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u64(rng);
- let b = gen_u64(rng);
- if b == 0 {
- return None;
- }
- let c = a % b;
- Some(Umoddi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::udiv::__umoddi3;
- static TEST_CASES: &[((u64, u64), u64)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn umoddi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __umoddi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Umodsi3 {
- a: u32,
- b: u32,
- c: u32,
- }
- impl TestCase for Umodsi3 {
- fn name() -> &'static str {
- "umodsi3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u32(rng);
- let b = gen_u32(rng);
- if b == 0 {
- return None;
- }
- let c = a % b;
- Some(Umodsi3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::udiv::__umodsi3;
- static TEST_CASES: &[((u32, u32), u32)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn umodsi3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __umodsi3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- #[derive(Eq, Hash, PartialEq)]
- pub struct Umodti3 {
- a: u128,
- b: u128,
- c: u128,
- }
- impl TestCase for Umodti3 {
- fn name() -> &'static str {
- "umodti3"
- }
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized,
- {
- let a = gen_u128(rng);
- let b = gen_u128(rng);
- if b == 0 {
- return None;
- }
- let c = a % b;
- Some(Umodti3 { a, b, c })
- }
- fn to_string(&self, buffer: &mut String) {
- writeln!(
- buffer,
- "(({a}, {b}), {c}),",
- a = self.a,
- b = self.b,
- c = self.c
- )
- .unwrap();
- }
- fn prologue() -> &'static str {
- "
- use compiler_builtins::int::udiv::__umodti3;
- static TEST_CASES: &[((u128, u128), u128)] = &[
- "
- }
- fn epilogue() -> &'static str {
- "
- ];
- #[test]
- fn umodti3() {
- for &((a, b), c) in TEST_CASES {
- let c_ = __umodti3(a, b);
- assert_eq!(((a, b), c), ((a, b), c_));
- }
- }
- "
- }
- }
- trait TestCase {
- /// Name of the intrinsic to test
- fn name() -> &'static str;
- /// Generates a valid test case
- fn generate<R>(rng: &mut R) -> Option<Self>
- where
- R: Rng,
- Self: Sized;
- /// Stringifies a test case
- fn to_string(&self, buffer: &mut String);
- /// Prologue of the test file
- fn prologue() -> &'static str;
- /// Epilogue of the test file
- fn epilogue() -> &'static str;
- }
- const PROLOGUE: &'static str = r#"
- extern crate compiler_builtins;
- // test runner
- #[cfg(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test))]
- extern crate utest_cortex_m_qemu;
- // overrides `panic!`
- #[cfg(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test))]
- #[macro_use]
- extern crate utest_macros;
- #[cfg(all(target_arch = "arm",
- not(any(target_env = "gnu", target_env = "musl")),
- target_os = "linux",
- test))]
- macro_rules! panic {
- ($($tt:tt)*) => {
- upanic!($($tt)*);
- };
- }
- "#;
- macro_rules! gen_int {
- ($name:ident, $ity:ident, $hty:ident) => {
- fn $name<R>(rng: &mut R) -> $ity
- where
- R: Rng,
- {
- let mut mk = || if rng.gen_weighted_bool(10) {
- *rng.choose(&[::std::$hty::MAX, 0, ::std::$hty::MIN]).unwrap()
- } else {
- rng.gen::<$hty>()
- };
- unsafe { mem::transmute([mk(), mk()]) }
- }
- }
- }
- gen_int!(gen_i32, i32, i16);
- gen_int!(gen_i64, i64, i32);
- gen_int!(gen_i128, i128, i64);
- macro_rules! gen_float {
- ($name:ident,
- $fty:ident,
- $uty:ident,
- $bits:expr,
- $significand_bits:expr) => {
- pub fn $name<R>(rng: &mut R) -> $fty
- where
- R: Rng,
- {
- const BITS: u8 = $bits;
- const SIGNIFICAND_BITS: u8 = $significand_bits;
- const SIGNIFICAND_MASK: $uty = (1 << SIGNIFICAND_BITS) - 1;
- const SIGN_MASK: $uty = (1 << (BITS - 1));
- const EXPONENT_MASK: $uty = !(SIGN_MASK | SIGNIFICAND_MASK);
- fn mk_f32(sign: bool, exponent: $uty, significand: $uty) -> $fty {
- unsafe {
- mem::transmute(((sign as $uty) << (BITS - 1)) |
- ((exponent & EXPONENT_MASK) <<
- SIGNIFICAND_BITS) |
- (significand & SIGNIFICAND_MASK))
- }
- }
- if rng.gen_weighted_bool(10) {
- // Special values
- *rng.choose(&[-0.0,
- 0.0,
- ::std::$fty::NAN,
- ::std::$fty::INFINITY,
- -::std::$fty::INFINITY])
- .unwrap()
- } else if rng.gen_weighted_bool(10) {
- // NaN patterns
- mk_f32(rng.gen(), rng.gen(), 0)
- } else if rng.gen() {
- // Denormalized
- mk_f32(rng.gen(), 0, rng.gen())
- } else {
- // Random anything
- mk_f32(rng.gen(), rng.gen(), rng.gen())
- }
- }
- }
- }
- gen_float!(gen_f32, f32, u32, 32, 23);
- gen_float!(gen_f64, f64, u64, 64, 52);
- pub fn gen_u128<R>(rng: &mut R) -> u128
- where
- R: Rng,
- {
- gen_i128(rng) as u128
- }
- pub fn gen_u32<R>(rng: &mut R) -> u32
- where
- R: Rng,
- {
- gen_i32(rng) as u32
- }
- fn gen_u64<R>(rng: &mut R) -> u64
- where
- R: Rng,
- {
- gen_i64(rng) as u64
- }
- pub fn to_u32(x: f32) -> u32 {
- unsafe { mem::transmute(x) }
- }
- pub fn to_u64(x: f64) -> u64 {
- unsafe { mem::transmute(x) }
- }
- fn mk_tests<T, R>(mut n: usize, rng: &mut R) -> String
- where
- T: Eq + Hash + TestCase,
- R: Rng,
- {
- let mut buffer = PROLOGUE.to_owned();
- buffer.push_str(T::prologue());
- let mut cases = HashSet::new();
- while n != 0 {
- if let Some(case) = T::generate(rng) {
- if cases.contains(&case) {
- continue;
- }
- case.to_string(&mut buffer);
- n -= 1;
- cases.insert(case);
- }
- }
- buffer.push_str(T::epilogue());
- buffer
- }
- fn mk_file<T>()
- where
- T: Eq + Hash + TestCase,
- {
- use std::io::Write;
- let rng = &mut rand::thread_rng();
- let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
- let out_file = out_dir.join(format!("{}.rs", T::name()));
- let contents = mk_tests::<T, _>(NTESTS, rng);
- File::create(out_file)
- .unwrap()
- .write_all(contents.as_bytes())
- .unwrap();
- }
- }
- #[cfg(feature = "c")]
- mod c {
- extern crate gcc;
- use std::collections::BTreeMap;
- use std::env;
- use std::path::Path;
- struct Sources {
- // SYMBOL -> PATH TO SOURCE
- map: BTreeMap<&'static str, &'static str>,
- }
- impl Sources {
- fn new() -> Sources {
- Sources { map: BTreeMap::new() }
- }
- fn extend(&mut self, sources: &[&'static str]) {
- // NOTE Some intrinsics have both a generic implementation (e.g.
- // `floatdidf.c`) and an arch optimized implementation
- // (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized
- // implementation and discard the generic implementation. If we don't
- // and keep both implementations, the linker will yell at us about
- // duplicate symbols!
- for &src in sources {
- let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap();
- if src.contains("/") {
- // Arch-optimized implementation (preferred)
- self.map.insert(symbol, src);
- } else {
- // Generic implementation
- if !self.map.contains_key(symbol) {
- self.map.insert(symbol, src);
- }
- }
- }
- }
- fn remove(&mut self, symbols: &[&str]) {
- for symbol in symbols {
- self.map.remove(*symbol).unwrap();
- }
- }
- }
- /// Compile intrinsics from the compiler-rt C source code
- pub fn compile(llvm_target: &[&str]) {
- let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
- let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
- let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
- let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
- let cfg = &mut gcc::Config::new();
- if target_env == "msvc" {
- // Don't pull in extra libraries on MSVC
- cfg.flag("/Zl");
- // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
- cfg.define("__func__", Some("__FUNCTION__"));
- } else {
- // Turn off various features of gcc and such, mostly copying
- // compiler-rt's build system already
- cfg.flag("-fno-builtin");
- cfg.flag("-fvisibility=hidden");
- cfg.flag("-fomit-frame-pointer");
- cfg.flag("-ffreestanding");
- cfg.define("VISIBILITY_HIDDEN", None);
- }
- // NOTE Most of the ARM intrinsics are written in assembly. Tell gcc which arch we are going
- // to target to make sure that the assembly implementations really work for the target. If
- // the implementation is not valid for the arch, then gcc will error when compiling it.
- if llvm_target[0].starts_with("thumb") {
- cfg.flag("-mthumb");
- if llvm_target.last() == Some(&"eabihf") {
- cfg.flag("-mfloat-abi=hard");
- }
- }
- if llvm_target[0] == "thumbv6m" {
- cfg.flag("-march=armv6-m");
- }
- if llvm_target[0] == "thumbv7m" {
- cfg.flag("-march=armv7-m");
- }
- if llvm_target[0] == "thumbv7em" {
- cfg.flag("-march=armv7e-m");
- }
- let mut sources = Sources::new();
- sources.extend(
- &[
- "absvdi2.c",
- "absvsi2.c",
- "addvdi3.c",
- "addvsi3.c",
- "apple_versioning.c",
- "clzdi2.c",
- "clzsi2.c",
- "cmpdi2.c",
- "comparedf2.c",
- "comparesf2.c",
- "ctzdi2.c",
- "ctzsi2.c",
- "divdc3.c",
- "divdf3.c",
- "divsc3.c",
- "divsf3.c",
- "divxc3.c",
- "extendsfdf2.c",
- "extendhfsf2.c",
- "ffsdi2.c",
- "fixdfdi.c",
- "fixdfsi.c",
- "fixsfdi.c",
- "fixsfsi.c",
- "fixunsdfdi.c",
- "fixunsdfsi.c",
- "fixunssfdi.c",
- "fixunssfsi.c",
- "fixunsxfdi.c",
- "fixunsxfsi.c",
- "fixxfdi.c",
- "floatdidf.c",
- "floatdisf.c",
- "floatdixf.c",
- "floatsidf.c",
- "floatsisf.c",
- "floatundidf.c",
- "floatundisf.c",
- "floatundixf.c",
- "floatunsidf.c",
- "floatunsisf.c",
- "int_util.c",
- "muldc3.c",
- "muldf3.c",
- "mulsc3.c",
- "mulsf3.c",
- "mulvdi3.c",
- "mulvsi3.c",
- "mulxc3.c",
- "negdf2.c",
- "negdi2.c",
- "negsf2.c",
- "negvdi2.c",
- "negvsi2.c",
- "paritydi2.c",
- "paritysi2.c",
- "popcountdi2.c",
- "popcountsi2.c",
- "powixf2.c",
- "subvdi3.c",
- "subvsi3.c",
- "truncdfhf2.c",
- "truncdfsf2.c",
- "truncsfhf2.c",
- "ucmpdi2.c",
- ],
- );
- if target_os != "ios" {
- sources.extend(
- &[
- "absvti2.c",
- "addvti3.c",
- "clzti2.c",
- "cmpti2.c",
- "ctzti2.c",
- "ffsti2.c",
- "fixdfti.c",
- "fixsfti.c",
- "fixunsdfti.c",
- "fixunssfti.c",
- "fixunsxfti.c",
- "fixxfti.c",
- "floattidf.c",
- "floattisf.c",
- "floattixf.c",
- "floatuntidf.c",
- "floatuntisf.c",
- "floatuntixf.c",
- "mulvti3.c",
- "negti2.c",
- "negvti2.c",
- "parityti2.c",
- "popcountti2.c",
- "subvti3.c",
- "ucmpti2.c",
- ],
- );
- }
- if target_vendor == "apple" {
- sources.extend(
- &[
- "atomic_flag_clear.c",
- "atomic_flag_clear_explicit.c",
- "atomic_flag_test_and_set.c",
- "atomic_flag_test_and_set_explicit.c",
- "atomic_signal_fence.c",
- "atomic_thread_fence.c",
- ],
- );
- }
- if target_env == "msvc" {
- if target_arch == "x86_64" {
- sources.extend(
- &[
- "x86_64/floatdidf.c",
- "x86_64/floatdisf.c",
- "x86_64/floatdixf.c",
- ],
- );
- }
- } else {
- if target_os != "freebsd" && target_os != "netbsd" {
- sources.extend(&["gcc_personality_v0.c"]);
- }
- if target_arch == "x86_64" {
- sources.extend(
- &[
- "x86_64/chkstk.S",
- "x86_64/chkstk2.S",
- "x86_64/floatdidf.c",
- "x86_64/floatdisf.c",
- "x86_64/floatdixf.c",
- "x86_64/floatundidf.S",
- "x86_64/floatundisf.S",
- "x86_64/floatundixf.S",
- ],
- );
- }
- if target_arch == "x86" {
- sources.extend(
- &[
- "i386/ashldi3.S",
- "i386/ashrdi3.S",
- "i386/chkstk.S",
- "i386/chkstk2.S",
- "i386/divdi3.S",
- "i386/floatdidf.S",
- "i386/floatdisf.S",
- "i386/floatdixf.S",
- "i386/floatundidf.S",
- "i386/floatundisf.S",
- "i386/floatundixf.S",
- "i386/lshrdi3.S",
- "i386/moddi3.S",
- "i386/muldi3.S",
- "i386/udivdi3.S",
- "i386/umoddi3.S",
- ],
- );
- }
- }
- if target_arch == "arm" && target_os != "ios" {
- sources.extend(
- &[
- "arm/aeabi_cdcmp.S",
- "arm/aeabi_cdcmpeq_check_nan.c",
- "arm/aeabi_cfcmp.S",
- "arm/aeabi_cfcmpeq_check_nan.c",
- "arm/aeabi_dcmp.S",
- "arm/aeabi_div0.c",
- "arm/aeabi_drsub.c",
- "arm/aeabi_fcmp.S",
- "arm/aeabi_frsub.c",
- "arm/bswapdi2.S",
- "arm/bswapsi2.S",
- "arm/clzdi2.S",
- "arm/clzsi2.S",
- "arm/comparesf2.S",
- "arm/divmodsi4.S",
- "arm/divsi3.S",
- "arm/modsi3.S",
- "arm/switch16.S",
- "arm/switch32.S",
- "arm/switch8.S",
- "arm/switchu8.S",
- "arm/sync_synchronize.S",
- "arm/udivmodsi4.S",
- "arm/udivsi3.S",
- "arm/umodsi3.S",
- ],
- );
- }
- if llvm_target[0] == "armv7" {
- sources.extend(
- &[
- "arm/sync_fetch_and_add_4.S",
- "arm/sync_fetch_and_add_8.S",
- "arm/sync_fetch_and_and_4.S",
- "arm/sync_fetch_and_and_8.S",
- "arm/sync_fetch_and_max_4.S",
- "arm/sync_fetch_and_max_8.S",
- "arm/sync_fetch_and_min_4.S",
- "arm/sync_fetch_and_min_8.S",
- "arm/sync_fetch_and_nand_4.S",
- "arm/sync_fetch_and_nand_8.S",
- "arm/sync_fetch_and_or_4.S",
- "arm/sync_fetch_and_or_8.S",
- "arm/sync_fetch_and_sub_4.S",
- "arm/sync_fetch_and_sub_8.S",
- "arm/sync_fetch_and_umax_4.S",
- "arm/sync_fetch_and_umax_8.S",
- "arm/sync_fetch_and_umin_4.S",
- "arm/sync_fetch_and_umin_8.S",
- "arm/sync_fetch_and_xor_4.S",
- "arm/sync_fetch_and_xor_8.S",
- ],
- );
- }
- if llvm_target.last().unwrap().ends_with("eabihf") {
- if !llvm_target[0].starts_with("thumbv7em") {
- sources.extend(
- &[
- "arm/adddf3vfp.S",
- "arm/addsf3vfp.S",
- "arm/divdf3vfp.S",
- "arm/divsf3vfp.S",
- "arm/eqdf2vfp.S",
- "arm/eqsf2vfp.S",
- "arm/extendsfdf2vfp.S",
- "arm/fixdfsivfp.S",
- "arm/fixsfsivfp.S",
- "arm/fixunsdfsivfp.S",
- "arm/fixunssfsivfp.S",
- "arm/floatsidfvfp.S",
- "arm/floatsisfvfp.S",
- "arm/floatunssidfvfp.S",
- "arm/floatunssisfvfp.S",
- "arm/gedf2vfp.S",
- "arm/gesf2vfp.S",
- "arm/gtdf2vfp.S",
- "arm/gtsf2vfp.S",
- "arm/ledf2vfp.S",
- "arm/lesf2vfp.S",
- "arm/ltdf2vfp.S",
- "arm/ltsf2vfp.S",
- "arm/muldf3vfp.S",
- "arm/mulsf3vfp.S",
- "arm/nedf2vfp.S",
- "arm/nesf2vfp.S",
- "arm/restore_vfp_d8_d15_regs.S",
- "arm/save_vfp_d8_d15_regs.S",
- "arm/subdf3vfp.S",
- "arm/subsf3vfp.S",
- ],
- );
- }
- sources.extend(&["arm/negdf2vfp.S", "arm/negsf2vfp.S"]);
- }
- if target_arch == "aarch64" {
- sources.extend(
- &[
- "comparetf2.c",
- "extenddftf2.c",
- "extendsftf2.c",
- "fixtfdi.c",
- "fixtfsi.c",
- "fixtfti.c",
- "fixunstfdi.c",
- "fixunstfsi.c",
- "fixunstfti.c",
- "floatditf.c",
- "floatsitf.c",
- "floatunditf.c",
- "floatunsitf.c",
- "multc3.c",
- "trunctfdf2.c",
- "trunctfsf2.c",
- ],
- );
- }
- // Remove the assembly implementations that won't compile for the target
- if llvm_target[0] == "thumbv6m" {
- sources.remove(
- &[
- "aeabi_cdcmp",
- "aeabi_cfcmp",
- "aeabi_dcmp",
- "aeabi_fcmp",
- "clzdi2",
- "clzsi2",
- "comparesf2",
- "divmodsi4",
- "divsi3",
- "modsi3",
- "switch16",
- "switch32",
- "switch8",
- "switchu8",
- "udivmodsi4",
- "udivsi3",
- "umodsi3",
- ],
- );
- // But use some generic implementations where possible
- sources.extend(&["clzdi2.c", "clzsi2.c"])
- }
- if llvm_target[0] == "thumbv7m" || llvm_target[0] == "thumbv7em" {
- sources.remove(&["aeabi_cdcmp", "aeabi_cfcmp"]);
- }
- let root = if env::var_os("CARGO_FEATURE_RUSTBUILD").is_some() {
- Path::new("../../libcompiler_builtins")
- } else {
- Path::new(".")
- };
- let src_dir = root.join("compiler-rt/lib/builtins");
- for src in sources.map.values() {
- let src = src_dir.join(src);
- cfg.file(&src);
- println!("cargo:rerun-if-changed={}", src.display());
- }
- cfg.compile("libcompiler-rt.a");
- }
- }
|