Explorar o código

Simplify how testing is done

All tests are moved to a separate crate in this repository to enable features by
default. Additionally the test generation is moved to a seprate build script and
simplified to reduce the amount of boilerplate needed per test.

Overall this should still be testing everything, just in a different location!
Alex Crichton %!s(int64=7) %!d(string=hai) anos
pai
achega
2a13475197
Modificáronse 88 ficheiros con 981 adicións e 6135 borrados
  1. 18 19
      Cargo.toml
  2. 0 5493
      build.rs
  3. 5 5
      ci/run.sh
  4. 5 4
      src/lib.rs
  5. 1 1
      src/macros.rs
  6. 25 0
      testcrate/Cargo.toml
  7. 914 0
      testcrate/build.rs
  8. 7 0
      testcrate/src/lib.rs
  9. 0 0
      testcrate/tests/aeabi_memclr.rs
  10. 0 0
      testcrate/tests/aeabi_memcpy.rs
  11. 0 0
      testcrate/tests/aeabi_memset.rs
  12. 6 0
      testcrate/tests/generated.rs
  13. 0 8
      tests/adddf3.rs
  14. 0 8
      tests/addsf3.rs
  15. 0 8
      tests/ashldi3.rs
  16. 0 8
      tests/ashlti3.rs
  17. 0 8
      tests/ashrdi3.rs
  18. 0 8
      tests/ashrti3.rs
  19. 0 7
      tests/divdf3.rs
  20. 0 8
      tests/divdf3vfp.rs
  21. 0 8
      tests/divdi3.rs
  22. 0 8
      tests/divmoddi4.rs
  23. 0 8
      tests/divmodsi4.rs
  24. 0 7
      tests/divsf3.rs
  25. 0 8
      tests/divsf3vfp.rs
  26. 0 8
      tests/divsi3.rs
  27. 0 10
      tests/divti3.rs
  28. 0 8
      tests/fixdfdi.rs
  29. 0 8
      tests/fixdfsi.rs
  30. 0 8
      tests/fixdfti.rs
  31. 0 8
      tests/fixsfdi.rs
  32. 0 8
      tests/fixsfsi.rs
  33. 0 8
      tests/fixsfti.rs
  34. 0 8
      tests/fixunsdfdi.rs
  35. 0 8
      tests/fixunsdfsi.rs
  36. 0 8
      tests/fixunsdfti.rs
  37. 0 8
      tests/fixunssfdi.rs
  38. 0 8
      tests/fixunssfsi.rs
  39. 0 8
      tests/fixunssfti.rs
  40. 0 8
      tests/floatdidf.rs
  41. 0 8
      tests/floatsidf.rs
  42. 0 8
      tests/floatsisf.rs
  43. 0 9
      tests/floattidf.rs
  44. 0 8
      tests/floattisf.rs
  45. 0 8
      tests/floatundidf.rs
  46. 0 8
      tests/floatunsidf.rs
  47. 0 8
      tests/floatunsisf.rs
  48. 0 8
      tests/floatuntidf.rs
  49. 0 8
      tests/floatuntisf.rs
  50. 0 7
      tests/gedf2.rs
  51. 0 7
      tests/gesf2.rs
  52. 0 8
      tests/i128_add.rs
  53. 0 8
      tests/i128_addo.rs
  54. 0 8
      tests/i128_sub.rs
  55. 0 8
      tests/i128_subo.rs
  56. 0 7
      tests/ledf2.rs
  57. 0 7
      tests/lesf2.rs
  58. 0 8
      tests/lshrdi3.rs
  59. 0 8
      tests/lshrti3.rs
  60. 0 8
      tests/moddi3.rs
  61. 0 8
      tests/modsi3.rs
  62. 0 10
      tests/modti3.rs
  63. 0 7
      tests/muldf3.rs
  64. 0 8
      tests/muldf3vfp.rs
  65. 0 8
      tests/muldi3.rs
  66. 0 8
      tests/mulodi4.rs
  67. 0 8
      tests/mulosi4.rs
  68. 0 10
      tests/muloti4.rs
  69. 0 7
      tests/mulsf3.rs
  70. 0 8
      tests/mulsf3vfp.rs
  71. 0 8
      tests/multi3.rs
  72. 0 8
      tests/powidf2.rs
  73. 0 8
      tests/powisf2.rs
  74. 0 8
      tests/subdf3.rs
  75. 0 8
      tests/subsf3.rs
  76. 0 8
      tests/u128_add.rs
  77. 0 8
      tests/u128_addo.rs
  78. 0 8
      tests/u128_sub.rs
  79. 0 8
      tests/u128_subo.rs
  80. 0 8
      tests/udivdi3.rs
  81. 0 8
      tests/udivmoddi4.rs
  82. 0 8
      tests/udivmodsi4.rs
  83. 0 10
      tests/udivmodti4.rs
  84. 0 8
      tests/udivsi3.rs
  85. 0 10
      tests/udivti3.rs
  86. 0 8
      tests/umoddi3.rs
  87. 0 8
      tests/umodsi3.rs
  88. 0 10
      tests/umodti3.rs

+ 18 - 19
Cargo.toml

@@ -1,38 +1,37 @@
 [package]
 authors = ["Jorge Aparicio <japaricious@gmail.com>"]
-build = "build.rs"
 name = "compiler_builtins"
 version = "0.1.0"
 
-[build-dependencies]
-cast = { version = "0.2.2", features = ["x128"], optional = true }
-rand = { version = "0.3.15", optional = true }
+[lib]
+test = false
 
-[build-dependencies.cc]
-optional = true
-version = "1.0"
+[build-dependencies]
+cc = { optional = true, version = "1.0" }
 
 [features]
+default = ["compiler-builtins"]
+
+# Enable compilation of C code in compiler-rt, filling in some more optimized
+# implementations and also filling in unimplemented intrinsics
 c = ["cc"]
+
+# Flag this library as the unstable compiler-builtins lib
 compiler-builtins = []
-default = ["compiler-builtins"]
+
+# Generate memory-related intrinsics like memcpy
 mem = []
-mangled-names = []
 
-# generate tests
-#
-# Note that this is an internal-only feature used in testing, this should not
-# be relied on with crates.io! Enabling this may expose you to breaking
-# changes.
-gen-tests = ["cast", "rand"]
+# Mangle all names so this can be linked in with other versions or other
+# compiler-rt implementations. Also used for testing
+mangled-names = []
 
-[target.'cfg(all(target_arch = "arm", not(any(target_env = "gnu", target_env = "musl")), target_os = "linux"))'.dev-dependencies]
-test = { git = "https://github.com/japaric/utest" }
-utest-cortex-m-qemu = { default-features = false, git = "https://github.com/japaric/utest" }
-utest-macros = { git = "https://github.com/japaric/utest" }
+# Don't generate lang items for i128 intrisnics and such
+no-lang-items = []
 
 [[example]]
 name = "intrinsics"
 required-features = ["c", "compiler-builtins"]
 
 [workspace]
+members = ["testcrate"]

+ 0 - 5493
build.rs

@@ -1,5 +1,3 @@
-#![feature(i128_type)]
-
 use std::env;
 
 fn main() {
@@ -23,10 +21,6 @@ fn main() {
     // custom targets, which can have arbitrary names.
     let llvm_target = target.split('-').collect::<Vec<_>>();
 
-    // Build test files
-    #[cfg(feature = "gen-tests")]
-    tests::generate();
-
     // Build missing intrinsics from compiler-rt C source code. If we're
     // mangling names though we assume that we're also in test mode so we don't
     // build anything and we rely on the upstream implementation of compiler-rt
@@ -57,5493 +51,6 @@ fn main() {
     }
 }
 
-#[cfg(feature = "gen-tests")]
-mod tests {
-    extern crate cast;
-    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::cast::{f32, f64, u32, u64, u128, i32, i64, i128};
-    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/cmp.rs
-            Gedf2,
-            Gesf2,
-            Ledf2,
-            Lesf2,
-
-            // float/conv.rs
-            Fixdfdi,
-            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,
-            Powisf2,
-
-            // float/sub.rs
-            Subdf3,
-            Subsf3,
-
-            // float/mul.rs
-            Mulsf3,
-            Muldf3,
-            Mulsf3vfp,
-            Muldf3vfp,
-
-            // float/div.rs
-            Divsf3,
-            Divdf3,
-            Divsf3vfp,
-            Divdf3vfp,
-
-            // int/addsub.rs
-            AddU128,
-            AddI128,
-            AddoU128,
-            AddoI128,
-            SubU128,
-            SubI128,
-            SuboU128,
-            SuboI128,
-
-            // 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,  // f64
-        b: u64,  // f64
-        c: u64,  // f64
-    }
-
-    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,  // f32
-        b: u32,  // f32
-        c: u32,  // f32
-    }
-
-    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 AddU128 {
-        a: u128,
-        b: u128,
-        c: u128,
-    }
-
-    impl TestCase for AddU128 {
-        fn name() -> &'static str {
-            "u128_add"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_u128(rng);
-            let b = gen_u128(rng);
-            let c = a.wrapping_add(b);
-
-            Some(AddU128 { 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::addsub::rust_u128_add;
-
-static TEST_CASES: &[((u128, u128), u128)] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn u128_add() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = rust_u128_add(a, b);
-        assert_eq!(((a, b), c), ((a, b), c_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct AddI128 {
-        a: i128,
-        b: i128,
-        c: i128,
-    }
-
-    impl TestCase for AddI128 {
-        fn name() -> &'static str {
-            "i128_add"
-        }
-
-        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_add(b);
-
-            Some(AddI128 { 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::addsub::rust_i128_add;
-
-static TEST_CASES: &[((i128, i128), i128)] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn i128_add() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = rust_i128_add(a, b);
-        assert_eq!(((a, b), c), ((a, b), c_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct AddoU128 {
-        a: u128,
-        b: u128,
-        c: u128,
-        d: bool,
-    }
-
-    impl TestCase for AddoU128 {
-        fn name() -> &'static str {
-            "u128_addo"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_u128(rng);
-            let b = gen_u128(rng);
-            let (c, d) = a.overflowing_add(b);
-
-            Some(AddoU128 { a, b, c, d })
-        }
-
-        fn to_string(&self, buffer: &mut String) {
-            writeln!(
-                buffer,
-                "(({a}, {b}), ({c}, {d})),",
-                a = self.a,
-                b = self.b,
-                c = self.c,
-                d = self.d
-            )
-                    .unwrap();
-        }
-
-        fn prologue() -> &'static str {
-            "
-use compiler_builtins::int::addsub::rust_u128_addo;
-
-static TEST_CASES: &[((u128, u128), (u128, bool))] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn u128_addo() {
-    for &((a, b), (c, d)) in TEST_CASES {
-        let (c_, d_) = rust_u128_addo(a, b);
-        assert_eq!(((a, b), (c, d)), ((a, b), (c_, d_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct AddoI128 {
-        a: i128,
-        b: i128,
-        c: i128,
-        d: bool,
-    }
-
-    impl TestCase for AddoI128 {
-        fn name() -> &'static str {
-            "i128_addo"
-        }
-
-        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, d) = a.overflowing_add(b);
-
-            Some(AddoI128 { a, b, c, d })
-        }
-
-        fn to_string(&self, buffer: &mut String) {
-            writeln!(
-                buffer,
-                "(({a}, {b}), ({c}, {d})),",
-                a = self.a,
-                b = self.b,
-                c = self.c,
-                d = self.d
-            )
-                    .unwrap();
-        }
-
-        fn prologue() -> &'static str {
-            "
-use compiler_builtins::int::addsub::rust_i128_addo;
-
-static TEST_CASES: &[((i128, i128), (i128, bool))] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn i128_addo() {
-    for &((a, b), (c, d)) in TEST_CASES {
-        let (c_, d_) = rust_i128_addo(a, b);
-        assert_eq!(((a, b), (c, d)), ((a, b), (c_, d_)));
-    }
-}
-"
-        }
-    }
-
-    #[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 Fixdfdi {
-        a: u64,  // f64
-        b: i64,
-    }
-
-    impl TestCase for Fixdfdi {
-        fn name() -> &'static str {
-            "fixdfdi"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f64(rng);
-            i64(a).ok().map(|b| Fixdfdi { 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::__fixdfdi;
-
-fn mk_f64(x: u64) -> f64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u64,), i64)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn fixdfdi() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __fixdfdi(mk_f64(a));
-        assert_eq!(((a,), b), ((a,), b_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Fixdfsi {
-        a: u64,  // f64
-        b: i32,
-    }
-
-    impl TestCase for Fixdfsi {
-        fn name() -> &'static str {
-            "fixdfsi"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f64(rng);
-            i32(a).ok().map(|b| Fixdfsi { 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::__fixdfsi;
-
-fn mk_f64(x: u64) -> f64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u64,), i32)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn fixdfdi() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __fixdfsi(mk_f64(a));
-        assert_eq!(((a,), b), ((a,), b_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Fixsfdi {
-        a: u32,  // f32
-        b: i64,
-    }
-
-    impl TestCase for Fixsfdi {
-        fn name() -> &'static str {
-            "fixsfdi"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f32(rng);
-            i64(a).ok().map(|b| Fixsfdi { 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::__fixsfdi;
-
-fn mk_f32(x: u32) -> f32 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u32,), i64)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn fixsfdi() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __fixsfdi(mk_f32(a));
-        assert_eq!(((a,), b), ((a,), b_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Fixsfsi {
-        a: u32,  // f32
-        b: i32,
-    }
-
-    impl TestCase for Fixsfsi {
-        fn name() -> &'static str {
-            "fixsfsi"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f32(rng);
-            i32(a).ok().map(|b| Fixsfsi { 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::__fixsfsi;
-
-fn mk_f32(x: u32) -> f32 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u32,), i32)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn fixsfsi() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __fixsfsi(mk_f32(a));
-        assert_eq!(((a,), b), ((a,), b_));
-    }
-}
-"
-        }
-    }
-
-    #[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
-        b: u64,
-    }
-
-    impl TestCase for Fixunsdfdi {
-        fn name() -> &'static str {
-            "fixunsdfdi"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f64(rng);
-            u64(a).ok().map(|b| Fixunsdfdi { 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::__fixunsdfdi;
-
-fn mk_f64(x: u64) -> f64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u64,), u64)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn fixunsdfdi() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __fixunsdfdi(mk_f64(a));
-        assert_eq!(((a,), b), ((a,), b_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Fixunsdfsi {
-        a: u64,  // f64
-        b: u32,
-    }
-
-    impl TestCase for Fixunsdfsi {
-        fn name() -> &'static str {
-            "fixunsdfsi"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f64(rng);
-            u32(a).ok().map(|b| Fixunsdfsi { 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::__fixunsdfsi;
-
-fn mk_f64(x: u64) -> f64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u64,), u32)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn fixunsdfdi() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __fixunsdfsi(mk_f64(a));
-        assert_eq!(((a,), b), ((a,), b_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Fixunssfdi {
-        a: u32,  // f32
-        b: u64,
-    }
-
-    impl TestCase for Fixunssfdi {
-        fn name() -> &'static str {
-            "fixunssfdi"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f32(rng);
-            u64(a).ok().map(|b| Fixunssfdi { 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::__fixunssfdi;
-
-fn mk_f32(x: u32) -> f32 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u32,), u64)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn fixunssfdi() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __fixunssfdi(mk_f32(a));
-        assert_eq!(((a,), b), ((a,), b_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Fixunssfsi {
-        a: u32,  // f32
-        b: u32,
-    }
-
-    impl TestCase for Fixunssfsi {
-        fn name() -> &'static str {
-            "fixunssfsi"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f32(rng);
-            u32(a).ok().map(|b| Fixunssfsi { 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::__fixunssfsi;
-
-fn mk_f32(x: u32) -> f32 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u32,), u32)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn fixunssfsi() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __fixunssfsi(mk_f32(a));
-        assert_eq!(((a,), b), ((a,), b_));
-    }
-}
-"
-        }
-    }
-
-    #[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,
-        b: u64, // f64
-    }
-
-    impl TestCase for Floatdidf {
-        fn name() -> &'static str {
-            "floatdidf"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_i64(rng);
-            Some(
-                Floatdidf {
-                    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::__floatdidf;
-
-fn to_u64(x: f64) -> u64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((i64,), u64)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn floatdidf() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __floatdidf(a);
-        assert_eq!(((a,), b), ((a,), to_u64(b_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Floatsidf {
-        a: i32,
-        b: u64, // f64
-    }
-
-    impl TestCase for Floatsidf {
-        fn name() -> &'static str {
-            "floatsidf"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_i32(rng);
-            Some(
-                Floatsidf {
-                    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::__floatsidf;
-
-fn to_u64(x: f64) -> u64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((i32,), u64)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn floatsidf() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __floatsidf(a);
-        assert_eq!(((a,), b), ((a,), to_u64(b_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Floatsisf {
-        a: i32,
-        b: u32, // f32
-    }
-
-    impl TestCase for Floatsisf {
-        fn name() -> &'static str {
-            "floatsisf"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_i32(rng);
-            Some(
-                Floatsisf {
-                    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::__floatsisf;
-
-fn to_u32(x: f32) -> u32 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((i32,), u32)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn floatsisf() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __floatsisf(a);
-        assert_eq!(((a,), b), ((a,), to_u32(b_)));
-    }
-}
-"
-        }
-    }
-
-    #[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,
-        b: u64, // f64
-    }
-
-    impl TestCase for Floatundidf {
-        fn name() -> &'static str {
-            "floatundidf"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_u64(rng);
-            Some(
-                Floatundidf {
-                    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::__floatundidf;
-
-fn to_u64(x: f64) -> u64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u64,), u64)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn floatundidf() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __floatundidf(a);
-        assert_eq!(((a,), b), ((a,), to_u64(b_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Floatunsidf {
-        a: u32,
-        b: u64, // f64
-    }
-
-    impl TestCase for Floatunsidf {
-        fn name() -> &'static str {
-            "floatunsidf"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_u32(rng);
-            Some(
-                Floatunsidf {
-                    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::__floatunsidf;
-
-fn to_u64(x: f64) -> u64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u32,), u64)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn floatunsidf() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __floatunsidf(a);
-        assert_eq!(((a,), b), ((a,), to_u64(b_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Floatunsisf {
-        a: u32,
-        b: u32, // f32
-    }
-
-    impl TestCase for Floatunsisf {
-        fn name() -> &'static str {
-            "floatunsisf"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_u32(rng);
-            Some(
-                Floatunsisf {
-                    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::__floatunsisf;
-
-fn to_u32(x: f32) -> u32 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u32,), u32)] = &[
-"#
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn floatunsisf() {
-    for &((a,), b) in TEST_CASES {
-        let b_ = __floatunsisf(a);
-        assert_eq!(((a,), b), ((a,), to_u32(b_)));
-    }
-}
-"
-        }
-    }
-
-    #[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 Gedf2 {
-        a: u64,
-        b: u64,
-        c: i32,
-    }
-
-    impl TestCase for Gedf2 {
-        fn name() -> &'static str {
-            "gedf2"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f64(rng);
-            let b = gen_f64(rng);
-            // 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() {
-                return None;
-            }
-
-            let c;
-            if a.is_nan() || b.is_nan() {
-                c = -1;
-            } else if a < b {
-                c = -1;
-            } else if a > b {
-                c = 1;
-            } else {
-                c = 0;
-            }
-
-            Some(Gedf2 { a: to_u64(a), b: to_u64(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 std::mem;
-use compiler_builtins::float::cmp::__gedf2;
-
-fn to_f64(x: u64) -> f64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u64, u64), i32)] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn gedf2() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __gedf2(to_f64(a), to_f64(b));
-        assert_eq!(((a, b), c), ((a, b), c_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Gesf2 {
-        a: u32,
-        b: u32,
-        c: i32,
-    }
-
-    impl TestCase for Gesf2 {
-        fn name() -> &'static str {
-            "gesf2"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f32(rng);
-            let b = gen_f32(rng);
-            // 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() {
-                return None;
-            }
-
-            let c;
-            if a.is_nan() || b.is_nan() {
-                c = -1;
-            } else if a < b {
-                c = -1;
-            } else if a > b {
-                c = 1;
-            } else {
-                c = 0;
-            }
-
-            Some(Gesf2 { a: to_u32(a), b: to_u32(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 std::mem;
-use compiler_builtins::float::cmp::__gesf2;
-
-fn to_f32(x: u32) -> f32 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u32, u32), i32)] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn gesf2() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __gesf2(to_f32(a), to_f32(b));
-        assert_eq!(((a, b), c), ((a, b), c_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Ledf2 {
-        a: u64,
-        b: u64,
-        c: i32,
-    }
-
-    impl TestCase for Ledf2 {
-        fn name() -> &'static str {
-            "ledf2"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f64(rng);
-            let b = gen_f64(rng);
-            // 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() {
-                return None;
-            }
-
-            let c;
-            if a.is_nan() || b.is_nan() {
-                c = 1;
-            } else if a < b {
-                c = -1;
-            } else if a > b {
-                c = 1;
-            } else {
-                c = 0;
-            }
-
-            Some(Ledf2 { a: to_u64(a), b: to_u64(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 std::mem;
-use compiler_builtins::float::cmp::__ledf2;
-
-fn to_f64(x: u64) -> f64 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u64, u64), i32)] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn ledf2() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __ledf2(to_f64(a), to_f64(b));
-        assert_eq!(((a, b), c), ((a, b), c_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Lesf2 {
-        a: u32,
-        b: u32,
-        c: i32,
-    }
-
-    impl TestCase for Lesf2 {
-        fn name() -> &'static str {
-            "lesf2"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_f32(rng);
-            let b = gen_f32(rng);
-            // 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() {
-                return None;
-            }
-
-            let c;
-            if a.is_nan() || b.is_nan() {
-                c = 1;
-            } else if a < b {
-                c = -1;
-            } else if a > b {
-                c = 1;
-            } else {
-                c = 0;
-            }
-
-            Some(Lesf2 { a: to_u32(a), b: to_u32(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 std::mem;
-use compiler_builtins::float::cmp::__lesf2;
-
-fn to_f32(x: u32) -> f32 {
-    unsafe { mem::transmute(x) }
-}
-
-static TEST_CASES: &[((u32, u32), i32)] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn lesf2() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __lesf2(to_f32(a), to_f32(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,  // f64
-        b: i32,
-        c: u64,  // f64
-    }
-
-    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,  // f32
-        b: i32,
-        c: u32,  // f32
-    }
-
-    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,  // f64
-        b: u64,  // f64
-        c: u64,  // f64
-    }
-
-    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,  // f32
-        b: u32,  // f32
-        c: u32,  // f32
-    }
-
-    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 SubU128 {
-        a: u128,
-        b: u128,
-        c: u128,
-    }
-
-    impl TestCase for SubU128 {
-        fn name() -> &'static str {
-            "u128_sub"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_u128(rng);
-            let b = gen_u128(rng);
-            let c = a.wrapping_sub(b);
-
-            Some(SubU128 { 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::addsub::rust_u128_sub;
-
-static TEST_CASES: &[((u128, u128), u128)] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn u128_sub() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = rust_u128_sub(a, b);
-        assert_eq!(((a, b), c), ((a, b), c_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct SubI128 {
-        a: i128,
-        b: i128,
-        c: i128,
-    }
-
-    impl TestCase for SubI128 {
-        fn name() -> &'static str {
-            "i128_sub"
-        }
-
-        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_sub(b);
-
-            Some(SubI128 { 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::addsub::rust_i128_sub;
-
-static TEST_CASES: &[((i128, i128), i128)] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn i128_sub() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = rust_i128_sub(a, b);
-        assert_eq!(((a, b), c), ((a, b), c_));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct SuboU128 {
-        a: u128,
-        b: u128,
-        c: u128,
-        d: bool,
-    }
-
-    impl TestCase for SuboU128 {
-        fn name() -> &'static str {
-            "u128_subo"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_u128(rng);
-            let b = gen_u128(rng);
-            let (c, d) = a.overflowing_sub(b);
-
-            Some(SuboU128 { a, b, c, d })
-        }
-
-        fn to_string(&self, buffer: &mut String) {
-            writeln!(
-                buffer,
-                "(({a}, {b}), ({c}, {d})),",
-                a = self.a,
-                b = self.b,
-                c = self.c,
-                d = self.d
-            )
-                    .unwrap();
-        }
-
-        fn prologue() -> &'static str {
-            "
-use compiler_builtins::int::addsub::rust_u128_subo;
-
-static TEST_CASES: &[((u128, u128), (u128, bool))] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn u128_subo() {
-    for &((a, b), (c, d)) in TEST_CASES {
-        let (c_, d_) = rust_u128_subo(a, b);
-        assert_eq!(((a, b), (c, d)), ((a, b), (c_, d_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct SuboI128 {
-        a: i128,
-        b: i128,
-        c: i128,
-        d: bool,
-    }
-
-    impl TestCase for SuboI128 {
-        fn name() -> &'static str {
-            "i128_subo"
-        }
-
-        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, d) = a.overflowing_sub(b);
-
-            Some(SuboI128 { a, b, c, d })
-        }
-
-        fn to_string(&self, buffer: &mut String) {
-            writeln!(
-                buffer,
-                "(({a}, {b}), ({c}, {d})),",
-                a = self.a,
-                b = self.b,
-                c = self.c,
-                d = self.d
-            )
-                    .unwrap();
-        }
-
-        fn prologue() -> &'static str {
-            "
-use compiler_builtins::int::addsub::rust_i128_subo;
-
-static TEST_CASES: &[((i128, i128), (i128, bool))] = &[
-"
-        }
-
-        fn epilogue() -> &'static str {
-            "
-];
-
-#[test]
-fn i128_subo() {
-    for &((a, b), (c, d)) in TEST_CASES {
-        let (c_, d_) = rust_i128_subo(a, b);
-        assert_eq!(((a, b), (c, d)), ((a, b), (c_, d_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Mulsf3 {
-        a: u32,  // f32
-        b: u32,  // f32
-        c: u32,  // f32
-    }
-
-    impl TestCase for Mulsf3 {
-        fn name() -> &'static str {
-            "mulsf3"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_large_f32(rng);
-            let b = gen_large_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(
-                Mulsf3 {
-                    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::mul::__mulsf3;
-
-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 mulsf3() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __mulsf3(mk_f32(a), mk_f32(b));
-        assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Muldf3 {
-        a: u64,  // f64
-        b: u64,  // f64
-        c: u64,  // f64
-    }
-
-    impl TestCase for Muldf3 {
-        fn name() -> &'static str {
-            "muldf3"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_large_f64(rng);
-            let b = gen_large_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(
-                Muldf3 {
-                    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::mul::__muldf3;
-
-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 muldf3() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __muldf3(mk_f64(a), mk_f64(b));
-        assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Mulsf3vfp {
-        a: u32,  // f32
-        b: u32,  // f32
-        c: u32,  // f32
-    }
-
-    impl TestCase for Mulsf3vfp {
-        fn name() -> &'static str {
-            "mulsf3vfp"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_large_f32(rng);
-            let b = gen_large_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(
-                Mulsf3vfp {
-                    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::mul::__mulsf3vfp;
-
-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 mulsf3vfp() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __mulsf3vfp(mk_f32(a), mk_f32(b));
-        assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Muldf3vfp {
-        a: u64,  // f64
-        b: u64,  // f64
-        c: u64,  // f64
-    }
-
-    impl TestCase for Muldf3vfp {
-        fn name() -> &'static str {
-            "muldf3vfp"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_large_f64(rng);
-            let b = gen_large_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(
-                Muldf3vfp {
-                    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::mul::__muldf3vfp;
-
-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 muldf3vfp() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __muldf3vfp(mk_f64(a), mk_f64(b));
-        assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
-    }
-}
-"
-        }
-    }
-
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Divsf3 {
-        a: u32,  // f32
-        b: u32,  // f32
-        c: u32,  // f32
-    }
-
-    impl TestCase for Divsf3 {
-        fn name() -> &'static str {
-            "divsf3"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_large_f32(rng);
-            let b = gen_large_f32(rng);
-            if b == 0.0 {
-                return None;
-            }
-            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()|| c.abs() <= unsafe { mem::transmute(16777215u32) } {
-                return None;
-            }
-
-            Some(
-                Divsf3 {
-                    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::div::__divsf3;
-
-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 divsf3() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __divsf3(mk_f32(a), mk_f32(b));
-        assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Divdf3 {
-        a: u64,  // f64
-        b: u64,  // f64
-        c: u64,  // f64
-    }
-
-    impl TestCase for Divdf3 {
-        fn name() -> &'static str {
-            "divdf3"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_large_f64(rng);
-            let b = gen_large_f64(rng);
-            if b == 0.0 {
-                return None;
-            }
-            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()
-                || c.abs() <= unsafe { mem::transmute(4503599627370495u64) } {
-                return None;
-            }
-
-            Some(
-                Divdf3 {
-                    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::div::__divdf3;
-
-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 divdf3() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __divdf3(mk_f64(a), mk_f64(b));
-        assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Divsf3vfp {
-        a: u32,  // f32
-        b: u32,  // f32
-        c: u32,  // f32
-    }
-
-    impl TestCase for Divsf3vfp {
-        fn name() -> &'static str {
-            "divsf3vfp"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_large_f32(rng);
-            let b = gen_large_f32(rng);
-            if b == 0.0 {
-                return None;
-            }
-            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()|| c.abs() <= unsafe { mem::transmute(16777215u32) } {
-                return None;
-            }
-
-            Some(
-                Divsf3vfp {
-                    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::div::__divsf3vfp;
-
-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 divsf3vfp() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __divsf3vfp(mk_f32(a), mk_f32(b));
-        assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
-    }
-}
-"
-        }
-    }
-
-    #[derive(Eq, Hash, PartialEq)]
-    pub struct Divdf3vfp {
-        a: u64,  // f64
-        b: u64,  // f64
-        c: u64,  // f64
-    }
-
-    impl TestCase for Divdf3vfp {
-        fn name() -> &'static str {
-            "divdf3vfp"
-        }
-
-        fn generate<R>(rng: &mut R) -> Option<Self>
-        where
-            R: Rng,
-            Self: Sized,
-        {
-            let a = gen_large_f64(rng);
-            let b = gen_large_f64(rng);
-            if b == 0.0 {
-                return None;
-            }
-            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()
-                || c.abs() <= unsafe { mem::transmute(4503599627370495u64) } {
-                return None;
-            }
-
-            Some(
-                Divdf3vfp {
-                    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::div::__divdf3vfp;
-
-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 divdf3vfp() {
-    for &((a, b), c) in TEST_CASES {
-        let c_ = __divdf3vfp(mk_f64(a), mk_f64(b));
-        assert_eq!(((a, b), c), ((a, b), to_u64(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);
-
-    macro_rules! gen_large_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
-                    rng.gen::<$fty>()
-                }
-            }
-        }
-    }
-
-    gen_large_float!(gen_large_f32, f32, u32, 32, 23);
-    gen_large_float!(gen_large_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_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)
-            .unwrap()
-            .write_all(contents.as_bytes())
-            .unwrap();
-    }
-}
-
 #[cfg(feature = "c")]
 mod c {
     extern crate cc;

+ 5 - 5
ci/run.sh

@@ -42,11 +42,11 @@ case $1 in
         done
         ;;
     *)
-        run="cargo test --no-default-features --target $1"
-        $run --features 'gen-tests mangled-names'
-        $run --features 'gen-tests mangled-names' --release
-        $run --features 'gen-tests mangled-names c'
-        $run --features 'gen-tests mangled-names c' --release
+        run="cargo test --manifest-path testcrate/Cargo.toml --target $1"
+        $run
+        $run --release
+        $run --features c
+        $run --features c --release
         ;;
 esac
 

+ 5 - 4
src/lib.rs

@@ -12,7 +12,6 @@
 #![feature(compiler_builtins)]
 #![feature(core_intrinsics)]
 #![feature(naked_functions)]
-#![feature(staged_api)]
 #![feature(i128_type)]
 #![feature(repr_simd)]
 #![feature(abi_unadjusted)]
@@ -20,9 +19,11 @@
 #![feature(lang_items)]
 #![allow(unused_features)]
 #![no_builtins]
-#![unstable(feature = "compiler_builtins_lib",
-            reason = "Compiler builtins. Will never become stable.",
-            issue = "0")]
+#![cfg_attr(feature = "compiler-builtins", feature(staged_api))]
+#![cfg_attr(feature = "compiler-builtins",
+            unstable(feature = "compiler_builtins_lib",
+                     reason = "Compiler builtins. Will never become stable.",
+                     issue = "0"))]
 
 // We disable #[no_mangle] for tests so that we can verify the test results
 // against the native compiler-rt implementations of the builtins.

+ 1 - 1
src/macros.rs

@@ -288,7 +288,7 @@ macro_rules! u128_lang_items {
             $($body:tt)*
         }
     )*) => ($(
-        #[cfg_attr(not(any(stage0, feature = "gen-tests")), lang = $lang)]
+        #[cfg_attr(not(any(stage0, feature = "no-lang-items")), lang = $lang)]
         pub fn $name( $($argname:  $ty),* ) -> $ret {
             $($body)*
         }

+ 25 - 0
testcrate/Cargo.toml

@@ -0,0 +1,25 @@
+[package]
+name = "testcrate"
+version = "0.1.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+
+[lib]
+test = false
+doctest = false
+
+[build-dependencies]
+cast = { version = "0.2.2", features = ["x128"] }
+rand = { version = "0.4", features = ["i128_support"] }
+
+[dependencies.compiler_builtins]
+path = ".."
+default-features = false
+features = ["mangled-names", "no-lang-items"]
+
+[target.'cfg(all(target_arch = "arm", not(any(target_env = "gnu", target_env = "musl")), target_os = "linux"))'.dev-dependencies]
+test = { git = "https://github.com/japaric/utest" }
+utest-cortex-m-qemu = { default-features = false, git = "https://github.com/japaric/utest" }
+utest-macros = { git = "https://github.com/japaric/utest" }
+
+[features]
+c = ["compiler_builtins/c"]

+ 914 - 0
testcrate/build.rs

@@ -0,0 +1,914 @@
+#![feature(i128_type, i128)]
+
+extern crate cast;
+extern crate rand;
+
+use std::collections::HashMap;
+use std::fmt::Write as FmtWrite;
+use std::fs::{self, OpenOptions};
+use std::io::Write;
+use std::hash::{Hash, Hasher};
+use std::path::PathBuf;
+use std::{env, mem};
+use std::fmt;
+
+use self::cast::{f32, f64, u32, u64, u128, i32, i64, i128};
+use self::rand::Rng;
+
+const NTESTS: usize = 1_000;
+
+fn main() {
+    let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let out_file = out_dir.join("generated.rs");
+    drop(fs::remove_file(&out_file));
+
+    let target = env::var("TARGET").unwrap();
+    let target_arch_arm =
+        target.contains("arm") ||
+        target.contains("thumb");
+    let target_arch_mips = target.contains("mips");
+
+    // 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)
+
+    // float/add.rs
+    gen(|(a, b): (MyF64, MyF64)| {
+            let c = a.0 + b.0;
+            if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
+                None
+            } else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::add::__adddf3(a, b)");
+    gen(|(a, b): (MyF32, MyF32)| {
+            let c = a.0 + b.0;
+            if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
+                None
+            } else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::add::__addsf3(a, b)");
+
+    // float/cmp.rs
+    gen(|(a, b): (MyF64, MyF64)| {
+            let (a, b) = (a.0, b.0);
+            if a.is_nan() || b.is_nan() {
+                return None;
+            }
+
+            if a.is_nan() || b.is_nan() {
+                Some(-1)
+            } else if a < b {
+                Some(-1)
+            } else if a > b {
+                Some(1)
+            } else {
+                Some(0)
+            }
+        },
+        "compiler_builtins::float::cmp::__gedf2(a, b)");
+    gen(|(a, b): (MyF32, MyF32)| {
+            let (a, b) = (a.0, b.0);
+            if a.is_nan() || b.is_nan() {
+                return None;
+            }
+
+            if a.is_nan() || b.is_nan() {
+                Some(-1)
+            } else if a < b {
+                Some(-1)
+            } else if a > b {
+                Some(1)
+            } else {
+                Some(0)
+            }
+        },
+        "compiler_builtins::float::cmp::__gesf2(a, b)");
+    gen(|(a, b): (MyF64, MyF64)| {
+            let (a, b) = (a.0, b.0);
+            if a.is_nan() || b.is_nan() {
+                return None;
+            }
+
+            if a.is_nan() || b.is_nan() {
+                Some(1)
+            } else if a < b {
+                Some(-1)
+            } else if a > b {
+                Some(1)
+            } else {
+                Some(0)
+            }
+        },
+        "compiler_builtins::float::cmp::__ledf2(a, b)");
+    gen(|(a, b): (MyF32, MyF32)| {
+            let (a, b) = (a.0, b.0);
+            if a.is_nan() || b.is_nan() {
+                return None;
+            }
+
+            if a.is_nan() || b.is_nan() {
+                Some(1)
+            } else if a < b {
+                Some(-1)
+            } else if a > b {
+                Some(1)
+            } else {
+                Some(0)
+            }
+        },
+        "compiler_builtins::float::cmp::__lesf2(a, b)");
+
+    // float/conv.rs
+    gen(|a: MyF64| i64(a.0).ok(),
+        "compiler_builtins::float::conv::__fixdfdi(a)");
+    gen(|a: MyF64| i32(a.0).ok(),
+        "compiler_builtins::float::conv::__fixdfsi(a)");
+    gen(|a: MyF32| i64(a.0).ok(),
+        "compiler_builtins::float::conv::__fixsfdi(a)");
+    gen(|a: MyF32| i32(a.0).ok(),
+        "compiler_builtins::float::conv::__fixsfsi(a)");
+    gen(|a: MyF32| i128(a.0).ok(),
+        "compiler_builtins::float::conv::__fixsfti(a)");
+    gen(|a: MyF64| i128(a.0).ok(),
+        "compiler_builtins::float::conv::__fixdfti(a)");
+    gen(|a: MyF64| u64(a.0).ok(),
+        "compiler_builtins::float::conv::__fixunsdfdi(a)");
+    gen(|a: MyF64| u32(a.0).ok(),
+        "compiler_builtins::float::conv::__fixunsdfsi(a)");
+    gen(|a: MyF32| u64(a.0).ok(),
+        "compiler_builtins::float::conv::__fixunssfdi(a)");
+    gen(|a: MyF32| u32(a.0).ok(),
+        "compiler_builtins::float::conv::__fixunssfsi(a)");
+    gen(|a: MyF32| u128(a.0).ok(),
+        "compiler_builtins::float::conv::__fixunssfti(a)");
+    gen(|a: MyF64| u128(a.0).ok(),
+        "compiler_builtins::float::conv::__fixunsdfti(a)");
+    gen(|a: MyI64| Some(f64(a.0)),
+        "compiler_builtins::float::conv::__floatdidf(a)");
+    gen(|a: MyI32| Some(f64(a.0)),
+        "compiler_builtins::float::conv::__floatsidf(a)");
+    gen(|a: MyI32| Some(f32(a.0)),
+        "compiler_builtins::float::conv::__floatsisf(a)");
+    gen(|a: MyU64| Some(f64(a.0)),
+        "compiler_builtins::float::conv::__floatundidf(a)");
+    gen(|a: MyU32| Some(f64(a.0)),
+        "compiler_builtins::float::conv::__floatunsidf(a)");
+    gen(|a: MyU32| Some(f32(a.0)),
+        "compiler_builtins::float::conv::__floatunsisf(a)");
+    gen(|a: MyU128| f32(a.0).ok(),
+        "compiler_builtins::float::conv::__floatuntisf(a)");
+    if !target_arch_mips {
+        gen(|a: MyI128| Some(f32(a.0)),
+            "compiler_builtins::float::conv::__floattisf(a)");
+        gen(|a: MyI128| Some(f64(a.0)),
+            "compiler_builtins::float::conv::__floattidf(a)");
+        gen(|a: MyU128| Some(f64(a.0)),
+            "compiler_builtins::float::conv::__floatuntidf(a)");
+    }
+
+    // float/pow.rs
+    gen(|(a, b): (MyF64, MyI32)| {
+			let c = a.0.powi(b.0);
+			if a.0.is_nan() || c.is_nan() {
+				None
+			} else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::pow::__powidf2(a, b)");
+    gen(|(a, b): (MyF32, MyI32)| {
+			let c = a.0.powi(b.0);
+			if a.0.is_nan() || c.is_nan() {
+				None
+			} else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::pow::__powisf2(a, b)");
+
+    // float/sub.rs
+    gen(|(a, b): (MyF64, MyF64)| {
+            let c = a.0 - b.0;
+            if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
+                None
+            } else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::sub::__subdf3(a, b)");
+    gen(|(a, b): (MyF32, MyF32)| {
+            let c = a.0 - b.0;
+            if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
+                None
+            } else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::sub::__subsf3(a, b)");
+
+    // float/mul.rs
+    gen(|(a, b): (MyF64, MyF64)| {
+            let c = a.0 * b.0;
+            if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
+                None
+            } else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::mul::__muldf3(a, b)");
+    gen(|(a, b): (LargeF32, LargeF32)| {
+            let c = a.0 * b.0;
+            if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
+                None
+            } else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::mul::__mulsf3(a, b)");
+
+    if target_arch_arm {
+        gen(|(a, b): (MyF64, MyF64)| {
+                let c = a.0 * b.0;
+                if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
+                    None
+                } else {
+                    Some(c)
+                }
+            },
+            "compiler_builtins::float::mul::__muldf3vfp(a, b)");
+        gen(|(a, b): (LargeF32, LargeF32)| {
+                let c = a.0 * b.0;
+                if a.0.is_nan() || b.0.is_nan() || c.is_nan() {
+                    None
+                } else {
+                    Some(c)
+                }
+            },
+            "compiler_builtins::float::mul::__mulsf3vfp(a, b)");
+    }
+
+    // float/div.rs
+    gen(|(a, b): (MyF64, MyF64)| {
+            if b.0 == 0.0 {
+                return None
+            }
+            let c = a.0 / b.0;
+            if a.0.is_nan() || b.0.is_nan() || c.is_nan() ||
+                c.abs() <= unsafe { mem::transmute(4503599627370495u64) }
+            {
+                None
+            } else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::div::__divdf3(a, b)");
+    gen(|(a, b): (LargeF32, LargeF32)| {
+            if b.0 == 0.0 {
+                return None
+            }
+            let c = a.0 / b.0;
+            if a.0.is_nan() || b.0.is_nan() || c.is_nan() ||
+                c.abs() <= unsafe { mem::transmute(16777215u32) }
+            {
+                None
+            } else {
+                Some(c)
+            }
+        },
+        "compiler_builtins::float::div::__divsf3(a, b)");
+
+    if target_arch_arm {
+        gen(|(a, b): (MyF64, MyF64)| {
+                if b.0 == 0.0 {
+                    return None
+                }
+                let c = a.0 / b.0;
+                if a.0.is_nan() || b.0.is_nan() || c.is_nan() ||
+                    c.abs() <= unsafe { mem::transmute(4503599627370495u64) }
+                {
+                    None
+                } else {
+                    Some(c)
+                }
+            },
+            "compiler_builtins::float::div::__divdf3vfp(a, b)");
+        gen(|(a, b): (LargeF32, LargeF32)| {
+                if b.0 == 0.0 {
+                    return None
+                }
+                let c = a.0 / b.0;
+                if a.0.is_nan() || b.0.is_nan() || c.is_nan() ||
+                    c.abs() <= unsafe { mem::transmute(16777215u32) }
+                {
+                    None
+                } else {
+                    Some(c)
+                }
+            },
+            "compiler_builtins::float::div::__divsf3vfp(a, b)");
+    }
+
+    // int/addsub.rs
+    gen(|(a, b): (MyU128, MyU128)| Some(a.0.wrapping_add(b.0)),
+        "compiler_builtins::int::addsub::rust_u128_add(a, b)");
+    gen(|(a, b): (MyI128, MyI128)| Some(a.0.wrapping_add(b.0)),
+        "compiler_builtins::int::addsub::rust_i128_add(a, b)");
+    gen(|(a, b): (MyU128, MyU128)| Some(a.0.overflowing_add(b.0)),
+        "compiler_builtins::int::addsub::rust_u128_addo(a, b)");
+    gen(|(a, b): (MyI128, MyI128)| Some(a.0.overflowing_add(b.0)),
+        "compiler_builtins::int::addsub::rust_i128_addo(a, b)");
+    gen(|(a, b): (MyU128, MyU128)| Some(a.0.wrapping_sub(b.0)),
+        "compiler_builtins::int::addsub::rust_u128_sub(a, b)");
+    gen(|(a, b): (MyI128, MyI128)| Some(a.0.wrapping_sub(b.0)),
+        "compiler_builtins::int::addsub::rust_i128_sub(a, b)");
+    gen(|(a, b): (MyU128, MyU128)| Some(a.0.overflowing_sub(b.0)),
+        "compiler_builtins::int::addsub::rust_u128_subo(a, b)");
+    gen(|(a, b): (MyI128, MyI128)| Some(a.0.overflowing_sub(b.0)),
+        "compiler_builtins::int::addsub::rust_i128_subo(a, b)");
+
+    // int/mul.rs
+    gen(|(a, b): (MyU64, MyU64)| Some(a.0.wrapping_mul(b.0)),
+        "compiler_builtins::int::mul::__muldi3(a, b)");
+    gen(|(a, b): (MyI64, MyI64)| Some(a.0.overflowing_mul(b.0)),
+        "{
+            let mut o = 2;
+            let c = compiler_builtins::int::mul::__mulodi4(a, b, &mut o);
+            (c, match o { 0 => false, 1 => true, _ => panic!() })
+        }");
+    gen(|(a, b): (MyI32, MyI32)| Some(a.0.overflowing_mul(b.0)),
+        "{
+            let mut o = 2;
+            let c = compiler_builtins::int::mul::__mulosi4(a, b, &mut o);
+            (c, match o { 0 => false, 1 => true, _ => panic!() })
+        }");
+    gen(|(a, b): (MyI128, MyI128)| Some(a.0.wrapping_mul(b.0)),
+        "compiler_builtins::int::mul::__multi3(a, b)");
+    if !target_arch_mips { // FIXME(#137)
+        gen(|(a, b): (MyI128, MyI128)| Some(a.0.overflowing_mul(b.0)),
+            "{
+                let mut o = 2;
+                let c = compiler_builtins::int::mul::__muloti4(a, b, &mut o);
+                (c, match o { 0 => false, 1 => true, _ => panic!() })
+            }");
+    }
+
+    // int/sdiv.rs
+    gen(|(a, b): (MyI64, MyI64)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some(a.0 / b.0)
+            }
+        },
+        "compiler_builtins::int::sdiv::__divdi3(a, b)");
+    gen(|(a, b): (MyI64, MyI64)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some((a.0 / b.0, a.0 % b.0))
+            }
+        },
+        "{
+            let mut r = 0;
+            (compiler_builtins::int::sdiv::__divmoddi4(a, b, &mut r), r)
+        }");
+    gen(|(a, b): (MyI32, MyI32)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some((a.0 / b.0, a.0 % b.0))
+            }
+        },
+        "{
+            let mut r = 0;
+            (compiler_builtins::int::sdiv::__divmodsi4(a, b, &mut r), r)
+        }");
+    gen(|(a, b): (MyI32, MyI32)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some(a.0 / b.0)
+            }
+        },
+        "compiler_builtins::int::sdiv::__divsi3(a, b)");
+    gen(|(a, b): (MyI32, MyI32)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some(a.0 % b.0)
+            }
+        },
+        "compiler_builtins::int::sdiv::__modsi3(a, b)");
+    gen(|(a, b): (MyI64, MyI64)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some(a.0 % b.0)
+            }
+        },
+        "compiler_builtins::int::sdiv::__moddi3(a, b)");
+    if !target_arch_mips { // FIXME(#137)
+        gen(|(a, b): (MyI128, MyI128)| {
+                if b.0 == 0 {
+                    None
+                } else {
+                    Some(a.0 / b.0)
+                }
+            },
+            "compiler_builtins::int::sdiv::__divti3(a, b)");
+        gen(|(a, b): (MyI128, MyI128)| {
+                if b.0 == 0 {
+                    None
+                } else {
+                    Some(a.0 % b.0)
+                }
+            },
+            "compiler_builtins::int::sdiv::__modti3(a, b)");
+    }
+
+    // int/shift.rs
+    gen(|(a, b): (MyU64, MyU32)| Some(a.0 << (b.0 % 64)),
+        "compiler_builtins::int::shift::__ashldi3(a, b % 64)");
+    gen(|(a, b): (MyU128, MyU32)| Some(a.0 << (b.0 % 128)),
+        "compiler_builtins::int::shift::__ashlti3(a, b % 128)");
+    gen(|(a, b): (MyI64, MyU32)| Some(a.0 >> (b.0 % 64)),
+        "compiler_builtins::int::shift::__ashrdi3(a, b % 64)");
+    gen(|(a, b): (MyI128, MyU32)| Some(a.0 >> (b.0 % 128)),
+        "compiler_builtins::int::shift::__ashrti3(a, b % 128)");
+    gen(|(a, b): (MyU64, MyU32)| Some(a.0 >> (b.0 % 64)),
+        "compiler_builtins::int::shift::__lshrdi3(a, b % 64)");
+    gen(|(a, b): (MyU128, MyU32)| Some(a.0 >> (b.0 % 128)),
+        "compiler_builtins::int::shift::__lshrti3(a, b % 128)");
+
+    // int/udiv.rs
+    gen(|(a, b): (MyU64, MyU64)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some(a.0 / b.0)
+            }
+        },
+        "compiler_builtins::int::udiv::__udivdi3(a, b)");
+    gen(|(a, b): (MyU64, MyU64)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some((a.0 / b.0, a.0 % b.0))
+            }
+        },
+        "{
+            let mut r = 0;
+            (compiler_builtins::int::udiv::__udivmoddi4(a, b, Some(&mut r)), r)
+        }");
+    gen(|(a, b): (MyU32, MyU32)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some((a.0 / b.0, a.0 % b.0))
+            }
+        },
+        "{
+            let mut r = 0;
+            (compiler_builtins::int::udiv::__udivmodsi4(a, b, Some(&mut r)), r)
+        }");
+    gen(|(a, b): (MyU32, MyU32)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some(a.0 / b.0)
+            }
+        },
+        "compiler_builtins::int::udiv::__udivsi3(a, b)");
+    gen(|(a, b): (MyU32, MyU32)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some(a.0 % b.0)
+            }
+        },
+        "compiler_builtins::int::udiv::__umodsi3(a, b)");
+    gen(|(a, b): (MyU64, MyU64)| {
+            if b.0 == 0 {
+                None
+            } else {
+                Some(a.0 % b.0)
+            }
+        },
+        "compiler_builtins::int::udiv::__umoddi3(a, b)");
+    if !target_arch_mips { // FIXME(#137)
+        gen(|(a, b): (MyU128, MyU128)| {
+                if b.0 == 0 {
+                    None
+                } else {
+                    Some(a.0 / b.0)
+                }
+            },
+            "compiler_builtins::int::udiv::__udivti3(a, b)");
+        gen(|(a, b): (MyU128, MyU128)| {
+                if b.0 == 0 {
+                    None
+                } else {
+                    Some(a.0 % b.0)
+                }
+            },
+            "compiler_builtins::int::udiv::__umodti3(a, b)");
+        gen(|(a, b): (MyU128, MyU128)| {
+                if b.0 == 0 {
+                    None
+                } else {
+                    Some((a.0 / b.0, a.0 % b.0))
+                }
+            },
+            "{
+                let mut r = 0;
+                (compiler_builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r)
+            }");
+    }
+}
+
+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);
+
+macro_rules! gen_large_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
+                rng.gen::<$fty>()
+            }
+        }
+    }
+}
+
+gen_large_float!(gen_large_f32, f32, u32, 32, 23);
+gen_large_float!(gen_large_f64, f64, u64, 64, 52);
+
+trait TestInput: rand::Rand + Hash + Eq + fmt::Debug {
+    fn ty_name() -> String;
+    fn generate_lets(container: &str, cnt: &mut u8) -> String;
+    fn generate_static(&self, dst: &mut String);
+}
+
+trait TestOutput {
+    fn ty_name() -> String;
+    fn generate_static(&self, dst: &mut String);
+    fn generate_expr(container: &str) -> String;
+}
+
+fn gen<F, A, R>(mut generate: F, test: &str)
+    where F: FnMut(A) -> Option<R>,
+          A: TestInput + Copy,
+          R: TestOutput,
+{
+    let rng = &mut rand::thread_rng();
+    let testname = test.split("::")
+        .last()
+        .unwrap()
+        .split("(")
+        .next()
+        .unwrap();
+    let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let out_file = out_dir.join("generated.rs");
+
+    let mut testcases = HashMap::new();
+    let mut n = NTESTS;
+    while n > 0 {
+        let input: A = rng.gen();
+        if testcases.contains_key(&input) {
+            continue
+        }
+        let output = match generate(input) {
+            Some(o) => o,
+            None => continue,
+        };
+        testcases.insert(input, output);
+        n -= 1;
+    }
+
+    let mut contents = String::new();
+    contents.push_str(&format!("mod {} {{\nuse super::*;\n", testname));
+    contents.push_str("#[test]\n");
+    contents.push_str("fn test() {\n");
+    contents.push_str(&format!("static TESTS: [({}, {}); {}] = [\n",
+                      A::ty_name(),
+                      R::ty_name(),
+                      NTESTS));
+    for (input, output) in testcases {
+        contents.push_str("    (");
+        input.generate_static(&mut contents);
+        contents.push_str(", ");
+        output.generate_static(&mut contents);
+        contents.push_str("),\n");
+    }
+    contents.push_str("];\n");
+
+    contents.push_str(&format!(r#"
+        for &(inputs, output) in TESTS.iter() {{
+            {}
+            assert_eq!({}, {}, "inputs {{:?}}", inputs)
+        }}
+    "#,
+        A::generate_lets("inputs", &mut 0),
+        R::generate_expr("output"),
+        test,
+    ));
+    contents.push_str("\n}\n");
+    contents.push_str("\n}\n");
+
+    OpenOptions::new()
+        .write(true)
+        .append(true)
+        .create(true)
+        .open(out_file)
+        .unwrap()
+        .write_all(contents.as_bytes())
+        .unwrap();
+}
+
+macro_rules! my_float {
+    ($(struct $name:ident($inner:ident) = $gen:ident;)*) => ($(
+        #[derive(Debug, Clone, Copy)]
+        struct $name($inner);
+
+        impl TestInput for $name {
+            fn ty_name() -> String {
+                format!("u{}", &stringify!($inner)[1..])
+            }
+
+            fn generate_lets(container: &str, cnt: &mut u8) -> String {
+                let me = *cnt;
+                *cnt += 1;
+                format!("let {} = {}::from_bits({});\n",
+                        (b'a' + me) as char,
+                        stringify!($inner),
+                        container)
+            }
+
+            fn generate_static(&self, dst: &mut String) {
+                write!(dst, "{}", self.0.to_bits()).unwrap();
+            }
+        }
+
+        impl rand::Rand for $name {
+            fn rand<R: rand::Rng>(r: &mut R) -> $name {
+                $name($gen(r))
+            }
+        }
+
+        impl Hash for $name {
+            fn hash<H: Hasher>(&self, h: &mut H) {
+                self.0.to_bits().hash(h)
+            }
+        }
+
+        impl PartialEq for $name {
+            fn eq(&self, other: &$name) -> bool {
+                self.0.to_bits() == other.0.to_bits()
+            }
+        }
+
+        impl Eq for $name {}
+
+    )*)
+}
+
+my_float! {
+    struct MyF64(f64) = gen_f64;
+    struct LargeF64(f64) = gen_large_f64;
+    struct MyF32(f32) = gen_f32;
+    struct LargeF32(f32) = gen_large_f32;
+}
+
+macro_rules! my_integer {
+    ($(struct $name:ident($inner:ident);)*) => ($(
+        #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
+        struct $name($inner);
+
+        impl TestInput for $name {
+            fn ty_name() -> String {
+                stringify!($inner).to_string()
+            }
+
+            fn generate_lets(container: &str, cnt: &mut u8) -> String {
+                let me = *cnt;
+                *cnt += 1;
+                format!("let {} = {};\n",
+                        (b'a' + me) as char,
+                        container)
+            }
+
+            fn generate_static(&self, dst: &mut String) {
+                write!(dst, "{}", self.0).unwrap();
+            }
+        }
+
+        impl rand::Rand for $name {
+            fn rand<R: rand::Rng>(rng: &mut R) -> $name {
+                let bits = (0 as $inner).count_zeros();
+                let mut mk = || {
+                    if rng.gen_weighted_bool(10) {
+                        *rng.choose(&[
+                            ::std::$inner::MAX >> (bits / 2),
+                            0,
+                            ::std::$inner::MIN >> (bits / 2),
+                        ]).unwrap()
+                    } else {
+                        rng.gen::<$inner>()
+                    }
+                };
+                let a = mk();
+                let b = mk();
+                $name((a << (bits / 2)) | (b & (!0 << (bits / 2))))
+            }
+        }
+    )*)
+}
+
+my_integer! {
+    struct MyI32(i32);
+    struct MyI64(i64);
+    struct MyI128(i128);
+    struct MyU32(u32);
+    struct MyU64(u64);
+    struct MyU128(u128);
+}
+
+impl<A, B> TestInput for (A, B)
+    where A: TestInput,
+          B: TestInput,
+{
+    fn ty_name() -> String {
+        format!("({}, {})", A::ty_name(), B::ty_name())
+    }
+
+    fn generate_lets(container: &str, cnt: &mut u8) -> String {
+        format!("{}{}",
+                A::generate_lets(&format!("{}.0", container), cnt),
+                B::generate_lets(&format!("{}.1", container), cnt))
+    }
+
+    fn generate_static(&self, dst: &mut String) {
+        dst.push_str("(");
+        self.0.generate_static(dst);
+        dst.push_str(", ");
+        self.1.generate_static(dst);
+        dst.push_str(")");
+    }
+}
+
+impl TestOutput for f64 {
+    fn ty_name() -> String {
+        "u64".to_string()
+    }
+
+    fn generate_static(&self, dst: &mut String) {
+        write!(dst, "{}", self.to_bits()).unwrap();
+    }
+
+    fn generate_expr(container: &str) -> String {
+        format!("f64::from_bits({})", container)
+    }
+}
+
+impl TestOutput for f32 {
+    fn ty_name() -> String {
+        "u32".to_string()
+    }
+
+    fn generate_static(&self, dst: &mut String) {
+        write!(dst, "{}", self.to_bits()).unwrap();
+    }
+
+    fn generate_expr(container: &str) -> String {
+        format!("f32::from_bits({})", container)
+    }
+}
+
+macro_rules! plain_test_output {
+    ($($i:tt)*) => ($(
+        impl TestOutput for $i {
+            fn ty_name() -> String {
+                stringify!($i).to_string()
+            }
+
+            fn generate_static(&self, dst: &mut String) {
+                write!(dst, "{}", self).unwrap();
+            }
+
+            fn generate_expr(container: &str) -> String {
+                container.to_string()
+            }
+        }
+    )*)
+}
+
+plain_test_output!(i32 i64 i128 u32 u64 u128 bool);
+
+impl<A, B> TestOutput for (A, B)
+    where A: TestOutput,
+          B: TestOutput,
+{
+    fn ty_name() -> String {
+        format!("({}, {})", A::ty_name(), B::ty_name())
+    }
+
+    fn generate_static(&self, dst: &mut String) {
+        dst.push_str("(");
+        self.0.generate_static(dst);
+        dst.push_str(", ");
+        self.1.generate_static(dst);
+        dst.push_str(")");
+    }
+
+    fn generate_expr(container: &str) -> String {
+        container.to_string()
+    }
+}

+ 7 - 0
testcrate/src/lib.rs

@@ -0,0 +1,7 @@
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn it_works() {
+        assert_eq!(2 + 2, 4);
+    }
+}

+ 0 - 0
tests/aeabi_memclr.rs → testcrate/tests/aeabi_memclr.rs


+ 0 - 0
tests/aeabi_memcpy.rs → testcrate/tests/aeabi_memcpy.rs


+ 0 - 0
tests/aeabi_memset.rs → testcrate/tests/aeabi_memset.rs


+ 6 - 0
testcrate/tests/generated.rs

@@ -0,0 +1,6 @@
+#![feature(i128_type)]
+#![allow(bad_style)]
+
+extern crate compiler_builtins;
+
+include!(concat!(env!("OUT_DIR"), "/generated.rs"));

+ 0 - 8
tests/adddf3.rs

@@ -1,8 +0,0 @@
-#![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"), "/adddf3.rs"));

+ 0 - 8
tests/addsf3.rs

@@ -1,8 +0,0 @@
-#![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"), "/addsf3.rs"));

+ 0 - 8
tests/ashldi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/ashldi3.rs"));

+ 0 - 8
tests/ashlti3.rs

@@ -1,8 +0,0 @@
-#![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"), "/ashlti3.rs"));

+ 0 - 8
tests/ashrdi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/ashrdi3.rs"));

+ 0 - 8
tests/ashrti3.rs

@@ -1,8 +0,0 @@
-#![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"), "/ashrti3.rs"));

+ 0 - 7
tests/divdf3.rs

@@ -1,7 +0,0 @@
-#![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"), "/divdf3.rs"));

+ 0 - 8
tests/divdf3vfp.rs

@@ -1,8 +0,0 @@
-#![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)]
-
-#[cfg(target_arch = "arm")]
-include!(concat!(env!("OUT_DIR"), "/divdf3vfp.rs"));

+ 0 - 8
tests/divdi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/divdi3.rs"));

+ 0 - 8
tests/divmoddi4.rs

@@ -1,8 +0,0 @@
-#![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"), "/divmoddi4.rs"));

+ 0 - 8
tests/divmodsi4.rs

@@ -1,8 +0,0 @@
-#![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"), "/divmodsi4.rs"));

+ 0 - 7
tests/divsf3.rs

@@ -1,7 +0,0 @@
-#![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"), "/divsf3.rs"));

+ 0 - 8
tests/divsf3vfp.rs

@@ -1,8 +0,0 @@
-#![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)]
-
-#[cfg(target_arch = "arm")]
-include!(concat!(env!("OUT_DIR"), "/divsf3vfp.rs"));

+ 0 - 8
tests/divsi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/divsi3.rs"));

+ 0 - 10
tests/divti3.rs

@@ -1,10 +0,0 @@
-#![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)]
-
-// FIXME(#137)
-#[cfg(not(target_arch = "mips"))]
-include!(concat!(env!("OUT_DIR"), "/divti3.rs"));

+ 0 - 8
tests/fixdfdi.rs

@@ -1,8 +0,0 @@
-#![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"), "/fixdfdi.rs"));

+ 0 - 8
tests/fixdfsi.rs

@@ -1,8 +0,0 @@
-#![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"), "/fixdfsi.rs"));

+ 0 - 8
tests/fixdfti.rs

@@ -1,8 +0,0 @@
-#![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"));

+ 0 - 8
tests/fixsfdi.rs

@@ -1,8 +0,0 @@
-#![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"), "/fixsfdi.rs"));

+ 0 - 8
tests/fixsfsi.rs

@@ -1,8 +0,0 @@
-#![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"), "/fixsfsi.rs"));

+ 0 - 8
tests/fixsfti.rs

@@ -1,8 +0,0 @@
-#![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"));

+ 0 - 8
tests/fixunsdfdi.rs

@@ -1,8 +0,0 @@
-#![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"), "/fixunsdfdi.rs"));

+ 0 - 8
tests/fixunsdfsi.rs

@@ -1,8 +0,0 @@
-#![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"), "/fixunsdfsi.rs"));

+ 0 - 8
tests/fixunsdfti.rs

@@ -1,8 +0,0 @@
-#![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"));

+ 0 - 8
tests/fixunssfdi.rs

@@ -1,8 +0,0 @@
-#![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"), "/fixunssfdi.rs"));

+ 0 - 8
tests/fixunssfsi.rs

@@ -1,8 +0,0 @@
-#![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"), "/fixunssfsi.rs"));

+ 0 - 8
tests/fixunssfti.rs

@@ -1,8 +0,0 @@
-#![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"));

+ 0 - 8
tests/floatdidf.rs

@@ -1,8 +0,0 @@
-#![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"), "/floatdidf.rs"));

+ 0 - 8
tests/floatsidf.rs

@@ -1,8 +0,0 @@
-#![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"), "/floatsidf.rs"));

+ 0 - 8
tests/floatsisf.rs

@@ -1,8 +0,0 @@
-#![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"), "/floatsisf.rs"));

+ 0 - 9
tests/floattidf.rs

@@ -1,9 +0,0 @@
-#![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)]
-#![cfg(not(target_arch = "mips"))] // FIXME(#168)
-
-include!(concat!(env!("OUT_DIR"), "/floattidf.rs"));

+ 0 - 8
tests/floattisf.rs

@@ -1,8 +0,0 @@
-#![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"));

+ 0 - 8
tests/floatundidf.rs

@@ -1,8 +0,0 @@
-#![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"), "/floatundidf.rs"));

+ 0 - 8
tests/floatunsidf.rs

@@ -1,8 +0,0 @@
-#![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"), "/floatunsidf.rs"));

+ 0 - 8
tests/floatunsisf.rs

@@ -1,8 +0,0 @@
-#![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"), "/floatunsisf.rs"));

+ 0 - 8
tests/floatuntidf.rs

@@ -1,8 +0,0 @@
-#![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"));

+ 0 - 8
tests/floatuntisf.rs

@@ -1,8 +0,0 @@
-#![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"));

+ 0 - 7
tests/gedf2.rs

@@ -1,7 +0,0 @@
-#![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"), "/gedf2.rs"));

+ 0 - 7
tests/gesf2.rs

@@ -1,7 +0,0 @@
-#![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"), "/gesf2.rs"));

+ 0 - 8
tests/i128_add.rs

@@ -1,8 +0,0 @@
-#![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"), "/i128_add.rs"));

+ 0 - 8
tests/i128_addo.rs

@@ -1,8 +0,0 @@
-#![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"), "/i128_addo.rs"));

+ 0 - 8
tests/i128_sub.rs

@@ -1,8 +0,0 @@
-#![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"), "/i128_sub.rs"));

+ 0 - 8
tests/i128_subo.rs

@@ -1,8 +0,0 @@
-#![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"), "/i128_subo.rs"));

+ 0 - 7
tests/ledf2.rs

@@ -1,7 +0,0 @@
-#![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"), "/ledf2.rs"));

+ 0 - 7
tests/lesf2.rs

@@ -1,7 +0,0 @@
-#![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"), "/lesf2.rs"));

+ 0 - 8
tests/lshrdi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/lshrdi3.rs"));

+ 0 - 8
tests/lshrti3.rs

@@ -1,8 +0,0 @@
-#![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"), "/lshrti3.rs"));

+ 0 - 8
tests/moddi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/moddi3.rs"));

+ 0 - 8
tests/modsi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/modsi3.rs"));

+ 0 - 10
tests/modti3.rs

@@ -1,10 +0,0 @@
-#![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)]
-
-// FIXME(#137)
-#[cfg(not(target_arch = "mips"))]
-include!(concat!(env!("OUT_DIR"), "/modti3.rs"));

+ 0 - 7
tests/muldf3.rs

@@ -1,7 +0,0 @@
-#![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"), "/muldf3.rs"));

+ 0 - 8
tests/muldf3vfp.rs

@@ -1,8 +0,0 @@
-#![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)]
-
-#[cfg(target_arch = "arm")]
-include!(concat!(env!("OUT_DIR"), "/muldf3vfp.rs"));

+ 0 - 8
tests/muldi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/muldi3.rs"));

+ 0 - 8
tests/mulodi4.rs

@@ -1,8 +0,0 @@
-#![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"), "/mulodi4.rs"));

+ 0 - 8
tests/mulosi4.rs

@@ -1,8 +0,0 @@
-#![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"), "/mulosi4.rs"));

+ 0 - 10
tests/muloti4.rs

@@ -1,10 +0,0 @@
-#![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)]
-
-// FIXME(#137)
-#[cfg(not(target_arch = "mips"))]
-include!(concat!(env!("OUT_DIR"), "/muloti4.rs"));

+ 0 - 7
tests/mulsf3.rs

@@ -1,7 +0,0 @@
-#![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"), "/mulsf3.rs"));

+ 0 - 8
tests/mulsf3vfp.rs

@@ -1,8 +0,0 @@
-#![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)]
-
-#[cfg(target_arch = "arm")]
-include!(concat!(env!("OUT_DIR"), "/mulsf3vfp.rs"));

+ 0 - 8
tests/multi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/multi3.rs"));

+ 0 - 8
tests/powidf2.rs

@@ -1,8 +0,0 @@
-#![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"), "/powidf2.rs"));

+ 0 - 8
tests/powisf2.rs

@@ -1,8 +0,0 @@
-#![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"), "/powisf2.rs"));

+ 0 - 8
tests/subdf3.rs

@@ -1,8 +0,0 @@
-#![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"), "/subdf3.rs"));

+ 0 - 8
tests/subsf3.rs

@@ -1,8 +0,0 @@
-#![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"), "/subsf3.rs"));

+ 0 - 8
tests/u128_add.rs

@@ -1,8 +0,0 @@
-#![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"), "/u128_add.rs"));

+ 0 - 8
tests/u128_addo.rs

@@ -1,8 +0,0 @@
-#![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"), "/u128_addo.rs"));

+ 0 - 8
tests/u128_sub.rs

@@ -1,8 +0,0 @@
-#![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"), "/u128_sub.rs"));

+ 0 - 8
tests/u128_subo.rs

@@ -1,8 +0,0 @@
-#![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"), "/u128_subo.rs"));

+ 0 - 8
tests/udivdi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/udivdi3.rs"));

+ 0 - 8
tests/udivmoddi4.rs

@@ -1,8 +0,0 @@
-#![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"), "/udivmoddi4.rs"));

+ 0 - 8
tests/udivmodsi4.rs

@@ -1,8 +0,0 @@
-#![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"), "/udivmodsi4.rs"));

+ 0 - 10
tests/udivmodti4.rs

@@ -1,10 +0,0 @@
-#![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)]
-
-// FIXME(#137)
-#[cfg(not(target_arch = "mips"))]
-include!(concat!(env!("OUT_DIR"), "/udivmodti4.rs"));

+ 0 - 8
tests/udivsi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/udivsi3.rs"));

+ 0 - 10
tests/udivti3.rs

@@ -1,10 +0,0 @@
-#![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)]
-
-// FIXME(#137)
-#[cfg(not(target_arch = "mips"))]
-include!(concat!(env!("OUT_DIR"), "/udivti3.rs"));

+ 0 - 8
tests/umoddi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/umoddi3.rs"));

+ 0 - 8
tests/umodsi3.rs

@@ -1,8 +0,0 @@
-#![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"), "/umodsi3.rs"));

+ 0 - 10
tests/umodti3.rs

@@ -1,10 +0,0 @@
-#![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)]
-
-// FIXME(#137)
-#[cfg(not(target_arch = "mips"))]
-include!(concat!(env!("OUT_DIR"), "/umodti3.rs"));