From 144e54d7b086d8f6ca48fac5b5a6521c07fb46a9 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 5 May 2017 23:31:41 +0200 Subject: [PATCH 01/16] Rename float conversion macros to something nicer --- src/float/conv.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/float/conv.rs b/src/float/conv.rs index efe590a..37aaa1c 100755 --- a/src/float/conv.rs +++ b/src/float/conv.rs @@ -12,7 +12,7 @@ macro_rules! fp_overflow { } } -macro_rules! fp_convert { +macro_rules! int_to_float { ($intrinsic:ident: $ity:ty, $fty:ty) => { pub extern "C" fn $intrinsic(i: $ity) -> $fty { @@ -82,12 +82,12 @@ macro_rules! fp_convert { } } -fp_convert!(__floatsisf: i32, f32); -fp_convert!(__floatsidf: i32, f64); -fp_convert!(__floatdidf: i64, f64); -fp_convert!(__floatunsisf: u32, f32); -fp_convert!(__floatunsidf: u32, f64); -fp_convert!(__floatundidf: u64, f64); +int_to_float!(__floatsisf: i32, f32); +int_to_float!(__floatsidf: i32, f64); +int_to_float!(__floatdidf: i64, f64); +int_to_float!(__floatunsisf: u32, f32); +int_to_float!(__floatunsidf: u32, f64); +int_to_float!(__floatundidf: u64, f64); #[derive(PartialEq, Debug)] enum Sign { @@ -95,7 +95,7 @@ enum Sign { Negative } -macro_rules! fp_fix { +macro_rules! float_to_int { ($intrinsic:ident: $fty:ty, $ity:ty) => { pub extern "C" fn $intrinsic(f: $fty) -> $ity { let fixint_min = <$ity>::min_value(); @@ -147,12 +147,12 @@ macro_rules! fp_fix { } } -fp_fix!(__fixsfsi: f32, i32); -fp_fix!(__fixsfdi: f32, i64); -fp_fix!(__fixdfsi: f64, i32); -fp_fix!(__fixdfdi: f64, i64); +float_to_int!(__fixsfsi: f32, i32); +float_to_int!(__fixsfdi: f32, i64); +float_to_int!(__fixdfsi: f64, i32); +float_to_int!(__fixdfdi: f64, i64); -fp_fix!(__fixunssfsi: f32, u32); -fp_fix!(__fixunssfdi: f32, u64); -fp_fix!(__fixunsdfsi: f64, u32); -fp_fix!(__fixunsdfdi: f64, u64); +float_to_int!(__fixunssfsi: f32, u32); +float_to_int!(__fixunssfdi: f32, u64); +float_to_int!(__fixunsdfsi: f64, u32); +float_to_int!(__fixunsdfdi: f64, u64); From 1ea9ea06d199423583e1379fa07ddd2f14c21250 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 00:42:59 +0200 Subject: [PATCH 02/16] Mark some float related intrinsics as implemented in README.md They have been implemented since --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 0810edf..2cd28d4 100644 --- a/README.md +++ b/README.md @@ -141,22 +141,22 @@ features = ["c"] - [x] divsi3.c - [ ] extendhfsf2.c - [ ] extendsfdf2.c -- [ ] fixdfdi.c -- [ ] fixdfsi.c -- [ ] fixsfdi.c -- [ ] fixsfsi.c -- [ ] fixunsdfdi.c -- [ ] fixunsdfsi.c -- [ ] fixunssfdi.c -- [ ] fixunssfsi.c -- [ ] floatdidf.c +- [x] fixdfdi.c +- [x] fixdfsi.c +- [x] fixsfdi.c +- [x] fixsfsi.c +- [x] fixunsdfdi.c +- [x] fixunsdfsi.c +- [x] fixunssfdi.c +- [x] fixunssfsi.c +- [x] floatdidf.c - [ ] floatdisf.c -- [ ] floatsidf.c -- [ ] floatsisf.c -- [ ] floatundidf.c +- [x] floatsidf.c +- [x] floatsisf.c +- [x] floatundidf.c - [ ] floatundisf.c -- [ ] floatunsidf.c -- [ ] floatunsisf.c +- [x] floatunsidf.c +- [x] floatunsisf.c - [ ] i386/ashldi3.S - [ ] i386/ashrdi3.S - [ ] i386/chkstk.S From f90792e1bcbd1ed7a012d9bfbdcc10abc9d669e6 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 02:22:54 +0200 Subject: [PATCH 03/16] Add i128 <-> float conversion functions --- src/float/conv.rs | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/float/conv.rs b/src/float/conv.rs index 37aaa1c..3413812 100755 --- a/src/float/conv.rs +++ b/src/float/conv.rs @@ -14,8 +14,11 @@ macro_rules! fp_overflow { macro_rules! int_to_float { ($intrinsic:ident: $ity:ty, $fty:ty) => { + int_to_float!($intrinsic: $ity, $fty, "C"); + }; + ($intrinsic:ident: $ity:ty, $fty:ty, $abi:tt) => { - pub extern "C" fn $intrinsic(i: $ity) -> $fty { + pub extern $abi fn $intrinsic(i: $ity) -> $fty { if i == 0 { return 0.0 } @@ -82,12 +85,25 @@ macro_rules! int_to_float { } } +macro_rules! int_to_float_unadj_on_win { + ($intrinsic:ident: $ity:ty, $fty:ty) => { + #[cfg(all(windows, target_pointer_width="64"))] + int_to_float!($intrinsic: $ity, $fty, "unadjusted"); + #[cfg(not(all(windows, target_pointer_width="64")))] + int_to_float!($intrinsic: $ity, $fty, "C"); + }; +} + int_to_float!(__floatsisf: i32, f32); int_to_float!(__floatsidf: i32, f64); int_to_float!(__floatdidf: i64, f64); +int_to_float_unadj_on_win!(__floattisf: i128, f32); +int_to_float_unadj_on_win!(__floattidf: i128, f64); int_to_float!(__floatunsisf: u32, f32); int_to_float!(__floatunsidf: u32, f64); int_to_float!(__floatundidf: u64, f64); +int_to_float_unadj_on_win!(__floatuntisf: u128, f32); +int_to_float_unadj_on_win!(__floatuntidf: u128, f64); #[derive(PartialEq, Debug)] enum Sign { @@ -97,7 +113,10 @@ enum Sign { macro_rules! float_to_int { ($intrinsic:ident: $fty:ty, $ity:ty) => { - pub extern "C" fn $intrinsic(f: $fty) -> $ity { + float_to_int!($intrinsic: $fty, $ity, "C"); + }; + ($intrinsic:ident: $fty:ty, $ity:ty, $abi:tt) => { + pub extern $abi fn $intrinsic(f: $fty) -> $ity { let fixint_min = <$ity>::min_value(); let fixint_max = <$ity>::max_value(); let fixint_bits = <$ity>::bits() as usize; @@ -147,12 +166,25 @@ macro_rules! float_to_int { } } +macro_rules! float_to_int_unadj_on_win { + ($intrinsic:ident: $fty:ty, $ity:ty) => { + #[cfg(all(windows, target_pointer_width="64"))] + float_to_int!($intrinsic: $fty, $ity, "unadjusted"); + #[cfg(not(all(windows, target_pointer_width="64")))] + float_to_int!($intrinsic: $fty, $ity, "C"); + }; +} + float_to_int!(__fixsfsi: f32, i32); float_to_int!(__fixsfdi: f32, i64); +float_to_int_unadj_on_win!(__fixsfti: f32, i128); float_to_int!(__fixdfsi: f64, i32); float_to_int!(__fixdfdi: f64, i64); +float_to_int_unadj_on_win!(__fixdfti: f64, i128); float_to_int!(__fixunssfsi: f32, u32); float_to_int!(__fixunssfdi: f32, u64); +float_to_int_unadj_on_win!(__fixunssfti: f32, u128); float_to_int!(__fixunsdfsi: f64, u32); float_to_int!(__fixunsdfdi: f64, u64); +float_to_int_unadj_on_win!(__fixunsdfti: f64, u128); From 9e7b61cb10b20eb6cf210cb4176148f5c70f84df Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 05:36:40 +0200 Subject: [PATCH 04/16] Use cast 0.2.1 for i128 support --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 59f6b40..3503438 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ name = "compiler_builtins" version = "0.1.0" [build-dependencies] -cast = { version = "0.2.0", optional = true } +cast = { version = "0.2.1", features = ["x128"], optional = true } rand = { version = "0.3.15", optional = true } [build-dependencies.gcc] From f9b5297ccc84c5331605c0541cb39a378a307f8c Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 05:20:20 +0200 Subject: [PATCH 05/16] Implement tests for floattidf and floattisf --- build.rs | 136 ++++++++++++++++++++++++++++++++++++++++++++- tests/floattidf.rs | 8 +++ tests/floattisf.rs | 8 +++ 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 tests/floattidf.rs create mode 100644 tests/floattisf.rs diff --git a/build.rs b/build.rs index ac75e6e..bbe9daf 100644 --- a/build.rs +++ b/build.rs @@ -49,7 +49,7 @@ mod tests { use std::path::PathBuf; use std::{env, mem}; - use self::cast::{f32, f64, u32, u64, i32, i64}; + use self::cast::{f32, f64, u32, u64, u128, i32, i64, i128}; use self::rand::Rng; const NTESTS: usize = 10_000; @@ -81,6 +81,8 @@ mod tests { Floatdidf, Floatsidf, Floatsisf, + Floattisf, + Floattidf, Floatundidf, Floatunsidf, Floatunsisf, @@ -1536,6 +1538,138 @@ fn floatsisf() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct Floattisf { + a: i128, + b: u32, // f32 + } + + impl TestCase for Floattisf { + fn name() -> &'static str { + "floattisf" + } + + fn generate(rng: &mut R) -> Option + 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(rng: &mut R) -> Option + 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); + assert_eq!(((a,), b), ((a,), to_u64(b_))); + } +} +" + } + } + #[derive(Eq, Hash, PartialEq)] pub struct Floatundidf { a: u64, diff --git a/tests/floattidf.rs b/tests/floattidf.rs new file mode 100644 index 0000000..4e4f84d --- /dev/null +++ b/tests/floattidf.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/floattidf.rs")); diff --git a/tests/floattisf.rs b/tests/floattisf.rs new file mode 100644 index 0000000..2a0657d --- /dev/null +++ b/tests/floattisf.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/floattisf.rs")); From d188d3dc12f7e043e255d8452b8f5839822a7061 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 05:24:20 +0200 Subject: [PATCH 06/16] Implement tests for fixdfti and fixsfti --- build.rs | 124 +++++++++++++++++++++++++++++++++++++++++++++++ tests/fixdfti.rs | 8 +++ tests/fixsfti.rs | 8 +++ 3 files changed, 140 insertions(+) create mode 100644 tests/fixdfti.rs create mode 100644 tests/fixsfti.rs diff --git a/build.rs b/build.rs index bbe9daf..42f2b47 100644 --- a/build.rs +++ b/build.rs @@ -74,6 +74,8 @@ mod tests { Fixdfsi, Fixsfdi, Fixsfsi, + Fixsfti, + Fixdfti, Fixunsdfdi, Fixunsdfsi, Fixunssfdi, @@ -1096,6 +1098,128 @@ fn fixsfdi() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct Fixsfti { + a: u32, // f32 + b: i128, + } + + impl TestCase for Fixsfti { + fn name() -> &'static str { + "fixsfti" + } + + fn generate(rng: &mut R) -> Option + 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(rng: &mut R) -> Option + 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 diff --git a/tests/fixdfti.rs b/tests/fixdfti.rs new file mode 100644 index 0000000..5bae55e --- /dev/null +++ b/tests/fixdfti.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/fixdfti.rs")); diff --git a/tests/fixsfti.rs b/tests/fixsfti.rs new file mode 100644 index 0000000..653157d --- /dev/null +++ b/tests/fixsfti.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/fixsfti.rs")); From 2d2bf21f7369b390147c638febed773f98fccee6 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 05:28:40 +0200 Subject: [PATCH 07/16] Implement tests for fixunsdfti and fixunssfti --- build.rs | 124 ++++++++++++++++++++++++++++++++++++++++++++ tests/fixunsdfti.rs | 8 +++ tests/fixunssfti.rs | 8 +++ 3 files changed, 140 insertions(+) create mode 100644 tests/fixunsdfti.rs create mode 100644 tests/fixunssfti.rs diff --git a/build.rs b/build.rs index 42f2b47..7af4717 100644 --- a/build.rs +++ b/build.rs @@ -80,6 +80,8 @@ mod tests { Fixunsdfsi, Fixunssfdi, Fixunssfsi, + Fixunssfti, + Fixunsdfti, Floatdidf, Floatsidf, Floatsisf, @@ -1464,6 +1466,128 @@ fn fixunssfsi() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct Fixunssfti { + a: u32, // f32 + b: u128, + } + + impl TestCase for Fixunssfti { + fn name() -> &'static str { + "fixunssfti" + } + + fn generate(rng: &mut R) -> Option + 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(rng: &mut R) -> Option + 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, diff --git a/tests/fixunsdfti.rs b/tests/fixunsdfti.rs new file mode 100644 index 0000000..615e7b3 --- /dev/null +++ b/tests/fixunsdfti.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/fixunsdfti.rs")); diff --git a/tests/fixunssfti.rs b/tests/fixunssfti.rs new file mode 100644 index 0000000..d67f9e7 --- /dev/null +++ b/tests/fixunssfti.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/fixunssfti.rs")); From b91c39da7378166760ed4394f8b527f892335d81 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 05:32:51 +0200 Subject: [PATCH 08/16] Implement tests for floatuntidf and floatuntisf --- build.rs | 134 +++++++++++++++++++++++++++++++++++++++++++ tests/floatuntidf.rs | 8 +++ tests/floatuntisf.rs | 8 +++ 3 files changed, 150 insertions(+) create mode 100644 tests/floatuntidf.rs create mode 100644 tests/floatuntisf.rs diff --git a/build.rs b/build.rs index 7af4717..bcb7fbe 100644 --- a/build.rs +++ b/build.rs @@ -90,6 +90,8 @@ mod tests { Floatundidf, Floatunsidf, Floatunsisf, + Floatuntisf, + Floatuntidf, // float/pow.rs Powidf2, @@ -2116,6 +2118,138 @@ fn floatunsisf() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct Floatuntisf { + a: u128, + b: u32, // f32 + } + + impl TestCase for Floatuntisf { + fn name() -> &'static str { + "floatuntisf" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_u128(rng); + Some( + Floatuntisf { + 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::__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(rng: &mut R) -> Option + 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); + assert_eq!(((a,), b), ((a,), to_u64(b_))); + } +} +" + } + } + #[derive(Eq, Hash, PartialEq)] pub struct Moddi3 { a: i64, diff --git a/tests/floatuntidf.rs b/tests/floatuntidf.rs new file mode 100644 index 0000000..4ea272e --- /dev/null +++ b/tests/floatuntidf.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/floatuntidf.rs")); diff --git a/tests/floatuntisf.rs b/tests/floatuntisf.rs new file mode 100644 index 0000000..74cd853 --- /dev/null +++ b/tests/floatuntisf.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/floatuntisf.rs")); From b87066750927a9f00b08acbe866190c3bf26cbb9 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 15:29:43 +0200 Subject: [PATCH 09/16] Adjust for changed cast function --- build.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/build.rs b/build.rs index bcb7fbe..7c4135d 100644 --- a/build.rs +++ b/build.rs @@ -2135,12 +2135,13 @@ fn floatunsisf() { Self: Sized, { let a = gen_u128(rng); - Some( + let f_a = f32(a); + f_a.ok().map(|f| { Floatuntisf { a, - b: to_u32(f32(a)), - }, - ) + b: to_u32(f), + } + }) } fn to_string(&self, buffer: &mut String) { From d247c55d4de2bdc4bff8e4355d03af1a0b009b35 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 05:33:28 +0200 Subject: [PATCH 10/16] Mark the functions just implemented in README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2cd28d4..5f59b44 100644 --- a/README.md +++ b/README.md @@ -196,14 +196,14 @@ These builtins are needed to support 128-bit integers, which are in the process - [x] ashlti3.c - [x] ashrti3.c - [x] divti3.c -- [ ] fixdfti.c -- [ ] fixsfti.c -- [ ] fixunsdfti.c -- [ ] fixunssfti.c -- [ ] floattidf.c -- [ ] floattisf.c -- [ ] floatuntidf.c -- [ ] floatuntisf.c +- [x] fixdfti.c +- [x] fixsfti.c +- [x] fixunsdfti.c +- [x] fixunssfti.c +- [x] floattidf.c +- [x] floattisf.c +- [x] floatuntidf.c +- [x] floatuntisf.c - [x] lshrti3.c - [x] modti3.c - [x] muloti4.c From e24673b6c7cd6b39a6f17f0ebd658d390a740ca7 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 6 May 2017 05:34:50 +0200 Subject: [PATCH 11/16] Fix test name gotten wrong --- build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.rs b/build.rs index 7c4135d..ba8c5e0 100644 --- a/build.rs +++ b/build.rs @@ -1092,7 +1092,7 @@ static TEST_CASES: &[((u32,), i32)] = &[ ]; #[test] -fn fixsfdi() { +fn fixsfsi() { for &((a,), b) in TEST_CASES { let b_ = __fixsfsi(mk_f32(a)); assert_eq!(((a,), b), ((a,), b_)); From 191c0be298d66d978adcd81e3a64e30d600569f0 Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 7 May 2017 03:03:58 +0200 Subject: [PATCH 12/16] Print generated files --- build.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.rs b/build.rs index ba8c5e0..1ae8b41 100644 --- a/build.rs +++ b/build.rs @@ -3934,7 +3934,9 @@ macro_rules! panic { let rng = &mut rand::thread_rng(); let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - let out_file = out_dir.join(format!("{}.rs", T::name())); + let out_file_name = format!("{}.rs", T::name()); + let out_file = out_dir.join(&out_file_name); + println!("Generating {}", out_file_name); let contents = mk_tests::(NTESTS, rng); File::create(out_file) From e574d8be4148f095462f9681c7da1fbc36415a3f Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 8 May 2017 00:05:00 +0200 Subject: [PATCH 13/16] Update cast to 0.2.2 to fix bug in debug mode --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3503438..e23c666 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ name = "compiler_builtins" version = "0.1.0" [build-dependencies] -cast = { version = "0.2.1", features = ["x128"], optional = true } +cast = { version = "0.2.2", features = ["x128"], optional = true } rand = { version = "0.3.15", optional = true } [build-dependencies.gcc] From 6047cdf1e83c4d20438ef461bb00348800580d1b Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 8 May 2017 00:49:36 +0200 Subject: [PATCH 14/16] floattidf, floatuntidf: ignore differences smaller than 2 in test Its possible that the generated f64 is different from the expected one by one bit. This is legal when both values are equally close to the i128/u128. --- build.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.rs b/build.rs index 1ae8b41..1b2aab1 100644 --- a/build.rs +++ b/build.rs @@ -1913,7 +1913,8 @@ static TEST_CASES: &[((i128,), u64)] = &[ fn floattidf() { for &((a,), b) in TEST_CASES { let b_ = __floattidf(a); - assert_eq!(((a,), b), ((a,), to_u64(b_))); + let diff = if to_u64(b_) > b { to_u64(b_) - b } else { b - to_u64(b_) }; + assert_eq!(((a,), b, true), ((a,), b, diff <= 1)); } } " @@ -2244,7 +2245,8 @@ static TEST_CASES: &[((u128,), u64)] = &[ fn floatuntidf() { for &((a,), b) in TEST_CASES { let b_ = __floatuntidf(a); - assert_eq!(((a,), b), ((a,), to_u64(b_))); + let diff = if to_u64(b_) > b { to_u64(b_) - b } else { b - to_u64(b_) }; + assert_eq!(((a,), b, true), ((a,), b, diff <= 1)); } } " From 673a6f9948a0076a3def3d23d2cb56ed501e233c Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 8 May 2017 04:03:16 +0200 Subject: [PATCH 15/16] Fix overflow bug when creating the absolute value Previously, the tests failed on some platforms due to it. --- src/int/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/int/mod.rs b/src/int/mod.rs index a94a070..768b6b4 100755 --- a/src/int/mod.rs +++ b/src/int/mod.rs @@ -63,7 +63,7 @@ macro_rules! int_impl { fn extract_sign(self) -> (bool, $uty) { if self < 0 { - (true, !(self as $uty) + 1) + (true, (!(self as $uty)).wrapping_add(1)) } else { (false, self as $uty) } From 258feadae4b9e1a15385f7163c5900b326704550 Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 10 May 2017 02:41:29 +0200 Subject: [PATCH 16/16] Build.rs: better debug output --- build.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/build.rs b/build.rs index 1b2aab1..c8179fe 100644 --- a/build.rs +++ b/build.rs @@ -1913,8 +1913,9 @@ static TEST_CASES: &[((i128,), u64)] = &[ fn floattidf() { for &((a,), b) in TEST_CASES { let b_ = __floattidf(a); - let diff = if to_u64(b_) > b { to_u64(b_) - b } else { b - to_u64(b_) }; - assert_eq!(((a,), b, true), ((a,), b, diff <= 1)); + 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)); } } " @@ -2245,8 +2246,9 @@ static TEST_CASES: &[((u128,), u64)] = &[ fn floatuntidf() { for &((a,), b) in TEST_CASES { let b_ = __floatuntidf(a); - let diff = if to_u64(b_) > b { to_u64(b_) - b } else { b - to_u64(b_) }; - assert_eq!(((a,), b, true), ((a,), b, diff <= 1)); + 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)); } } "