Prechádzať zdrojové kódy

Auto merge of #161 - est31:i128, r=japaric

Implement i128 <-> float conversion functions

Implements {u,i}128 <-> float conversion functions.
bors 8 rokov pred
rodič
commit
f3ace11071

+ 1 - 1
Cargo.toml

@@ -5,7 +5,7 @@ name = "compiler_builtins"
 version = "0.1.0"
 
 [build-dependencies]
-cast = { version = "0.2.0", optional = true }
+cast = { version = "0.2.2", features = ["x128"], optional = true }
 rand = { version = "0.3.15", optional = true }
 
 [build-dependencies.gcc]

+ 22 - 22
README.md

@@ -141,22 +141,22 @@ features = ["c"]
 - [x] divsi3.c
 - [ ] extendhfsf2.c
 - [ ] extendsfdf2.c
-- [ ] fixdfdi.c
-- [ ] fixdfsi.c
-- [ ] fixsfdi.c
-- [ ] fixsfsi.c
-- [ ] fixunsdfdi.c
-- [ ] fixunsdfsi.c
-- [ ] fixunssfdi.c
-- [ ] fixunssfsi.c
-- [ ] floatdidf.c
+- [x] fixdfdi.c
+- [x] fixdfsi.c
+- [x] fixsfdi.c
+- [x] fixsfsi.c
+- [x] fixunsdfdi.c
+- [x] fixunsdfsi.c
+- [x] fixunssfdi.c
+- [x] fixunssfsi.c
+- [x] floatdidf.c
 - [ ] floatdisf.c
-- [ ] floatsidf.c
-- [ ] floatsisf.c
-- [ ] floatundidf.c
+- [x] floatsidf.c
+- [x] floatsisf.c
+- [x] floatundidf.c
 - [ ] floatundisf.c
-- [ ] floatunsidf.c
-- [ ] floatunsisf.c
+- [x] floatunsidf.c
+- [x] floatunsisf.c
 - [ ] i386/ashldi3.S
 - [ ] i386/ashrdi3.S
 - [ ] i386/chkstk.S
@@ -196,14 +196,14 @@ These builtins are needed to support 128-bit integers, which are in the process
 - [x] ashlti3.c
 - [x] ashrti3.c
 - [x] divti3.c
-- [ ] fixdfti.c
-- [ ] fixsfti.c
-- [ ] fixunsdfti.c
-- [ ] fixunssfti.c
-- [ ] floattidf.c
-- [ ] floattisf.c
-- [ ] floatuntidf.c
-- [ ] floatuntisf.c
+- [x] fixdfti.c
+- [x] fixsfti.c
+- [x] fixunsdfti.c
+- [x] fixunssfti.c
+- [x] floattidf.c
+- [x] floattisf.c
+- [x] floatuntidf.c
+- [x] floatuntisf.c
 - [x] lshrti3.c
 - [x] modti3.c
 - [x] muloti4.c

+ 526 - 3
build.rs

@@ -49,7 +49,7 @@ mod tests {
     use std::path::PathBuf;
     use std::{env, mem};
 
-    use self::cast::{f32, f64, u32, u64, i32, i64};
+    use self::cast::{f32, f64, u32, u64, u128, i32, i64, i128};
     use self::rand::Rng;
 
     const NTESTS: usize = 10_000;
@@ -74,16 +74,24 @@ mod tests {
             Fixdfsi,
             Fixsfdi,
             Fixsfsi,
+            Fixsfti,
+            Fixdfti,
             Fixunsdfdi,
             Fixunsdfsi,
             Fixunssfdi,
             Fixunssfsi,
+            Fixunssfti,
+            Fixunsdfti,
             Floatdidf,
             Floatsidf,
             Floatsisf,
+            Floattisf,
+            Floattidf,
             Floatundidf,
             Floatunsidf,
             Floatunsisf,
+            Floatuntisf,
+            Floatuntidf,
 
             // float/pow.rs
             Powidf2,
@@ -1084,7 +1092,7 @@ static TEST_CASES: &[((u32,), i32)] = &[
 ];
 
 #[test]
-fn fixsfdi() {
+fn fixsfsi() {
     for &((a,), b) in TEST_CASES {
         let b_ = __fixsfsi(mk_f32(a));
         assert_eq!(((a,), b), ((a,), b_));
@@ -1094,6 +1102,128 @@ fn fixsfdi() {
         }
     }
 
+    #[derive(Eq, Hash, PartialEq)]
+    pub struct Fixsfti {
+        a: u32,  // f32
+        b: i128,
+    }
+
+    impl TestCase for Fixsfti {
+        fn name() -> &'static str {
+            "fixsfti"
+        }
+
+        fn generate<R>(rng: &mut R) -> Option<Self>
+        where
+            R: Rng,
+            Self: Sized,
+        {
+            let a = gen_f32(rng);
+            i128(a).ok().map(|b| Fixsfti { a: to_u32(a), b })
+        }
+
+        fn to_string(&self, buffer: &mut String) {
+            writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).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::conv::__fixsfti;
+
+fn mk_f32(x: u32) -> f32 {
+    unsafe { mem::transmute(x) }
+}
+
+static TEST_CASES: &[((u32,), i128)] = &[
+"#
+        }
+
+        fn epilogue() -> &'static str {
+            "
+];
+
+#[test]
+fn fixsfti() {
+    for &((a,), b) in TEST_CASES {
+        let b_ = __fixsfti(mk_f32(a));
+        assert_eq!(((a,), b), ((a,), b_));
+    }
+}
+"
+        }
+    }
+
+    #[derive(Eq, Hash, PartialEq)]
+    pub struct Fixdfti {
+        a: u64,  // f64
+        b: i128,
+    }
+
+    impl TestCase for Fixdfti {
+        fn name() -> &'static str {
+            "fixdfti"
+        }
+
+        fn generate<R>(rng: &mut R) -> Option<Self>
+        where
+            R: Rng,
+            Self: Sized,
+        {
+            let a = gen_f64(rng);
+            i128(a).ok().map(|b| Fixdfti { a: to_u64(a), b })
+        }
+
+        fn to_string(&self, buffer: &mut String) {
+            writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).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::conv::__fixdfti;
+
+fn mk_f64(x: u64) -> f64 {
+    unsafe { mem::transmute(x) }
+}
+
+static TEST_CASES: &[((u64,), i128)] = &[
+"#
+        }
+
+        fn epilogue() -> &'static str {
+            "
+];
+
+#[test]
+fn fixdfti() {
+    for &((a,), b) in TEST_CASES {
+        let b_ = __fixdfti(mk_f64(a));
+        assert_eq!(((a,), b), ((a,), b_));
+    }
+}
+"
+        }
+    }
+
     #[derive(Eq, Hash, PartialEq)]
     pub struct Fixunsdfdi {
         a: u64,  // f64
@@ -1338,6 +1468,128 @@ fn fixunssfsi() {
         }
     }
 
+    #[derive(Eq, Hash, PartialEq)]
+    pub struct Fixunssfti {
+        a: u32,  // f32
+        b: u128,
+    }
+
+    impl TestCase for Fixunssfti {
+        fn name() -> &'static str {
+            "fixunssfti"
+        }
+
+        fn generate<R>(rng: &mut R) -> Option<Self>
+        where
+            R: Rng,
+            Self: Sized,
+        {
+            let a = gen_f32(rng);
+            u128(a).ok().map(|b| Fixunssfti { a: to_u32(a), b })
+        }
+
+        fn to_string(&self, buffer: &mut String) {
+            writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).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::conv::__fixunssfti;
+
+fn mk_f32(x: u32) -> f32 {
+    unsafe { mem::transmute(x) }
+}
+
+static TEST_CASES: &[((u32,), u128)] = &[
+"#
+        }
+
+        fn epilogue() -> &'static str {
+            "
+];
+
+#[test]
+fn fixunssfti() {
+    for &((a,), b) in TEST_CASES {
+        let b_ = __fixunssfti(mk_f32(a));
+        assert_eq!(((a,), b), ((a,), b_));
+    }
+}
+"
+        }
+    }
+
+    #[derive(Eq, Hash, PartialEq)]
+    pub struct Fixunsdfti  {
+        a: u64,  // f64
+        b: u128,
+    }
+
+    impl TestCase for Fixunsdfti {
+        fn name() -> &'static str {
+            "fixunsdfti"
+        }
+
+        fn generate<R>(rng: &mut R) -> Option<Self>
+        where
+            R: Rng,
+            Self: Sized,
+        {
+            let a = gen_f64(rng);
+            u128(a).ok().map(|b| Fixunsdfti { a: to_u64(a), b })
+        }
+
+        fn to_string(&self, buffer: &mut String) {
+            writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).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::conv::__fixunsdfti;
+
+fn mk_f64(x: u64) -> f64 {
+    unsafe { mem::transmute(x) }
+}
+
+static TEST_CASES: &[((u64,), u128)] = &[
+"#
+        }
+
+        fn epilogue() -> &'static str {
+            "
+];
+
+#[test]
+fn fixunsdfti() {
+    for &((a,), b) in TEST_CASES {
+        let b_ = __fixunsdfti(mk_f64(a));
+        assert_eq!(((a,), b), ((a,), b_));
+    }
+}
+"
+        }
+    }
+
     #[derive(Eq, Hash, PartialEq)]
     pub struct Floatdidf {
         a: i64,
@@ -1536,6 +1788,140 @@ fn floatsisf() {
         }
     }
 
+    #[derive(Eq, Hash, PartialEq)]
+    pub struct Floattisf {
+        a: i128,
+        b: u32, // f32
+    }
+
+    impl TestCase for Floattisf {
+        fn name() -> &'static str {
+            "floattisf"
+        }
+
+        fn generate<R>(rng: &mut R) -> Option<Self>
+        where
+            R: Rng,
+            Self: Sized,
+        {
+            let a = gen_i128(rng);
+            Some(
+                Floattisf {
+                    a,
+                    b: to_u32(f32(a)),
+                },
+            )
+        }
+
+        fn to_string(&self, buffer: &mut String) {
+            writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).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::conv::__floattisf;
+
+fn to_u32(x: f32) -> u32 {
+    unsafe { mem::transmute(x) }
+}
+
+static TEST_CASES: &[((i128,), u32)] = &[
+"#
+        }
+
+        fn epilogue() -> &'static str {
+            "
+];
+
+#[test]
+fn floattisf() {
+    for &((a,), b) in TEST_CASES {
+        let b_ = __floattisf(a);
+        assert_eq!(((a,), b), ((a,), to_u32(b_)));
+    }
+}
+"
+        }
+    }
+
+    #[derive(Eq, Hash, PartialEq)]
+    pub struct Floattidf {
+        a: i128,
+        b: u64, // f64
+    }
+
+    impl TestCase for Floattidf {
+        fn name() -> &'static str {
+            "floattidf"
+        }
+
+        fn generate<R>(rng: &mut R) -> Option<Self>
+        where
+            R: Rng,
+            Self: Sized,
+        {
+            let a = gen_i128(rng);
+            Some(
+                Floattidf {
+                    a,
+                    b: to_u64(f64(a)),
+                },
+            )
+        }
+
+        fn to_string(&self, buffer: &mut String) {
+            writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).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::conv::__floattidf;
+
+fn to_u64(x: f64) -> u64 {
+    unsafe { mem::transmute(x) }
+}
+
+static TEST_CASES: &[((i128,), u64)] = &[
+"#
+        }
+
+        fn epilogue() -> &'static str {
+            "
+];
+
+#[test]
+fn floattidf() {
+    for &((a,), b) in TEST_CASES {
+        let b_ = __floattidf(a);
+        let g_b = to_u64(b_);
+        let diff = if g_b > b { g_b - b } else { b - g_b };
+        assert_eq!(((a,), b, g_b, true), ((a,), b, g_b, diff <= 1));
+    }
+}
+"
+        }
+    }
+
     #[derive(Eq, Hash, PartialEq)]
     pub struct Floatundidf {
         a: u64,
@@ -1734,6 +2120,141 @@ fn floatunsisf() {
         }
     }
 
+    #[derive(Eq, Hash, PartialEq)]
+    pub struct Floatuntisf {
+        a: u128,
+        b: u32, // f32
+    }
+
+    impl TestCase for Floatuntisf {
+        fn name() -> &'static str {
+            "floatuntisf"
+        }
+
+        fn generate<R>(rng: &mut R) -> Option<Self>
+        where
+            R: Rng,
+            Self: Sized,
+        {
+            let a = gen_u128(rng);
+            let f_a = f32(a);
+            f_a.ok().map(|f| {
+                Floatuntisf {
+                    a,
+                    b: to_u32(f),
+                }
+            })
+        }
+
+        fn to_string(&self, buffer: &mut String) {
+            writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).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::conv::__floatuntisf;
+
+fn to_u32(x: f32) -> u32 {
+    unsafe { mem::transmute(x) }
+}
+
+static TEST_CASES: &[((u128,), u32)] = &[
+"#
+        }
+
+        fn epilogue() -> &'static str {
+            "
+];
+
+#[test]
+fn floatuntisf() {
+    for &((a,), b) in TEST_CASES {
+        let b_ = __floatuntisf(a);
+        assert_eq!(((a,), b), ((a,), to_u32(b_)));
+    }
+}
+"
+        }
+    }
+
+    #[derive(Eq, Hash, PartialEq)]
+    pub struct Floatuntidf {
+        a: u128,
+        b: u64, // f64
+    }
+
+    impl TestCase for Floatuntidf {
+        fn name() -> &'static str {
+            "floatuntidf"
+        }
+
+        fn generate<R>(rng: &mut R) -> Option<Self>
+        where
+            R: Rng,
+            Self: Sized,
+        {
+            let a = gen_u128(rng);
+            Some(
+                Floatuntidf {
+                    a,
+                    b: to_u64(f64(a)),
+                },
+            )
+        }
+
+        fn to_string(&self, buffer: &mut String) {
+            writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).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::conv::__floatuntidf;
+
+fn to_u64(x: f64) -> u64 {
+    unsafe { mem::transmute(x) }
+}
+
+static TEST_CASES: &[((u128,), u64)] = &[
+"#
+        }
+
+        fn epilogue() -> &'static str {
+            "
+];
+
+#[test]
+fn floatuntidf() {
+    for &((a,), b) in TEST_CASES {
+        let b_ = __floatuntidf(a);
+        let g_b = to_u64(b_);
+        let diff = if g_b > b { g_b - b } else { b - g_b };
+        assert_eq!(((a,), b, g_b, true), ((a,), b, g_b, diff <= 1));
+    }
+}
+"
+        }
+    }
+
     #[derive(Eq, Hash, PartialEq)]
     pub struct Moddi3 {
         a: i64,
@@ -3417,7 +3938,9 @@ macro_rules! panic {
 
         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 out_file_name = format!("{}.rs", T::name());
+        let out_file = out_dir.join(&out_file_name);
+        println!("Generating {}", out_file_name);
         let contents = mk_tests::<T, _>(NTESTS, rng);
 
         File::create(out_file)

+ 50 - 18
src/float/conv.rs

@@ -12,10 +12,13 @@ macro_rules! fp_overflow {
     }
 }
 
-macro_rules! fp_convert {
+macro_rules! int_to_float {
     ($intrinsic:ident: $ity:ty, $fty:ty) => {
+        int_to_float!($intrinsic: $ity, $fty, "C");
+    };
+    ($intrinsic:ident: $ity:ty, $fty:ty, $abi:tt) => {
 
-    pub extern "C" fn $intrinsic(i: $ity) -> $fty {
+    pub extern $abi fn $intrinsic(i: $ity) -> $fty {
         if i == 0 {
             return 0.0
         }
@@ -82,12 +85,25 @@ macro_rules! fp_convert {
     }
 }
 
-fp_convert!(__floatsisf: i32, f32);
-fp_convert!(__floatsidf: i32, f64);
-fp_convert!(__floatdidf: i64, f64);
-fp_convert!(__floatunsisf: u32, f32);
-fp_convert!(__floatunsidf: u32, f64);
-fp_convert!(__floatundidf: u64, f64);
+macro_rules! int_to_float_unadj_on_win {
+    ($intrinsic:ident: $ity:ty, $fty:ty) => {
+        #[cfg(all(windows, target_pointer_width="64"))]
+        int_to_float!($intrinsic: $ity, $fty, "unadjusted");
+        #[cfg(not(all(windows, target_pointer_width="64")))]
+        int_to_float!($intrinsic: $ity, $fty, "C");
+    };
+}
+
+int_to_float!(__floatsisf: i32, f32);
+int_to_float!(__floatsidf: i32, f64);
+int_to_float!(__floatdidf: i64, f64);
+int_to_float_unadj_on_win!(__floattisf: i128, f32);
+int_to_float_unadj_on_win!(__floattidf: i128, f64);
+int_to_float!(__floatunsisf: u32, f32);
+int_to_float!(__floatunsidf: u32, f64);
+int_to_float!(__floatundidf: u64, f64);
+int_to_float_unadj_on_win!(__floatuntisf: u128, f32);
+int_to_float_unadj_on_win!(__floatuntidf: u128, f64);
 
 #[derive(PartialEq, Debug)]
 enum Sign {
@@ -95,9 +111,12 @@ enum Sign {
     Negative
 }
 
-macro_rules! fp_fix {
+macro_rules! float_to_int {
     ($intrinsic:ident: $fty:ty, $ity:ty) => {
-        pub extern "C" fn $intrinsic(f: $fty) -> $ity {
+        float_to_int!($intrinsic: $fty, $ity, "C");
+    };
+    ($intrinsic:ident: $fty:ty, $ity:ty, $abi:tt) => {
+        pub extern $abi fn $intrinsic(f: $fty) -> $ity {
             let fixint_min = <$ity>::min_value();
             let fixint_max = <$ity>::max_value();
             let fixint_bits = <$ity>::bits() as usize;
@@ -147,12 +166,25 @@ macro_rules! fp_fix {
     }
 }
 
-fp_fix!(__fixsfsi: f32, i32);
-fp_fix!(__fixsfdi: f32, i64);
-fp_fix!(__fixdfsi: f64, i32);
-fp_fix!(__fixdfdi: f64, i64);
+macro_rules! float_to_int_unadj_on_win {
+    ($intrinsic:ident: $fty:ty, $ity:ty) => {
+        #[cfg(all(windows, target_pointer_width="64"))]
+        float_to_int!($intrinsic: $fty, $ity, "unadjusted");
+        #[cfg(not(all(windows, target_pointer_width="64")))]
+        float_to_int!($intrinsic: $fty, $ity, "C");
+    };
+}
 
-fp_fix!(__fixunssfsi: f32, u32);
-fp_fix!(__fixunssfdi: f32, u64);
-fp_fix!(__fixunsdfsi: f64, u32);
-fp_fix!(__fixunsdfdi: f64, u64);
+float_to_int!(__fixsfsi: f32, i32);
+float_to_int!(__fixsfdi: f32, i64);
+float_to_int_unadj_on_win!(__fixsfti: f32, i128);
+float_to_int!(__fixdfsi: f64, i32);
+float_to_int!(__fixdfdi: f64, i64);
+float_to_int_unadj_on_win!(__fixdfti: f64, i128);
+
+float_to_int!(__fixunssfsi: f32, u32);
+float_to_int!(__fixunssfdi: f32, u64);
+float_to_int_unadj_on_win!(__fixunssfti: f32, u128);
+float_to_int!(__fixunsdfsi: f64, u32);
+float_to_int!(__fixunsdfdi: f64, u64);
+float_to_int_unadj_on_win!(__fixunsdfti: f64, u128);

+ 1 - 1
src/int/mod.rs

@@ -63,7 +63,7 @@ macro_rules! int_impl {
 
             fn extract_sign(self) -> (bool, $uty) {
                 if self < 0 {
-                    (true, !(self as $uty) + 1)
+                    (true, (!(self as $uty)).wrapping_add(1))
                 } else {
                     (false, self as $uty)
                 }

+ 8 - 0
tests/fixdfti.rs

@@ -0,0 +1,8 @@
+#![feature(compiler_builtins_lib)]
+#![feature(i128_type)]
+#![cfg_attr(all(target_arch = "arm",
+                not(any(target_env = "gnu", target_env = "musl")),
+                target_os = "linux",
+                test), no_std)]
+
+include!(concat!(env!("OUT_DIR"), "/fixdfti.rs"));

+ 8 - 0
tests/fixsfti.rs

@@ -0,0 +1,8 @@
+#![feature(compiler_builtins_lib)]
+#![feature(i128_type)]
+#![cfg_attr(all(target_arch = "arm",
+                not(any(target_env = "gnu", target_env = "musl")),
+                target_os = "linux",
+                test), no_std)]
+
+include!(concat!(env!("OUT_DIR"), "/fixsfti.rs"));

+ 8 - 0
tests/fixunsdfti.rs

@@ -0,0 +1,8 @@
+#![feature(compiler_builtins_lib)]
+#![feature(i128_type)]
+#![cfg_attr(all(target_arch = "arm",
+                not(any(target_env = "gnu", target_env = "musl")),
+                target_os = "linux",
+                test), no_std)]
+
+include!(concat!(env!("OUT_DIR"), "/fixunsdfti.rs"));

+ 8 - 0
tests/fixunssfti.rs

@@ -0,0 +1,8 @@
+#![feature(compiler_builtins_lib)]
+#![feature(i128_type)]
+#![cfg_attr(all(target_arch = "arm",
+                not(any(target_env = "gnu", target_env = "musl")),
+                target_os = "linux",
+                test), no_std)]
+
+include!(concat!(env!("OUT_DIR"), "/fixunssfti.rs"));

+ 8 - 0
tests/floattidf.rs

@@ -0,0 +1,8 @@
+#![feature(compiler_builtins_lib)]
+#![feature(i128_type)]
+#![cfg_attr(all(target_arch = "arm",
+                not(any(target_env = "gnu", target_env = "musl")),
+                target_os = "linux",
+                test), no_std)]
+
+include!(concat!(env!("OUT_DIR"), "/floattidf.rs"));

+ 8 - 0
tests/floattisf.rs

@@ -0,0 +1,8 @@
+#![feature(compiler_builtins_lib)]
+#![feature(i128_type)]
+#![cfg_attr(all(target_arch = "arm",
+                not(any(target_env = "gnu", target_env = "musl")),
+                target_os = "linux",
+                test), no_std)]
+
+include!(concat!(env!("OUT_DIR"), "/floattisf.rs"));

+ 8 - 0
tests/floatuntidf.rs

@@ -0,0 +1,8 @@
+#![feature(compiler_builtins_lib)]
+#![feature(i128_type)]
+#![cfg_attr(all(target_arch = "arm",
+                not(any(target_env = "gnu", target_env = "musl")),
+                target_os = "linux",
+                test), no_std)]
+
+include!(concat!(env!("OUT_DIR"), "/floatuntidf.rs"));

+ 8 - 0
tests/floatuntisf.rs

@@ -0,0 +1,8 @@
+#![feature(compiler_builtins_lib)]
+#![feature(i128_type)]
+#![cfg_attr(all(target_arch = "arm",
+                not(any(target_env = "gnu", target_env = "musl")),
+                target_os = "linux",
+                test), no_std)]
+
+include!(concat!(env!("OUT_DIR"), "/floatuntisf.rs"));