Auto merge of #161 - est31:i128, r=japaric
Implement i128 <-> float conversion functions Implements {u,i}128 <-> float conversion functions.
This commit is contained in:
commit
f3ace11071
|
@ -5,7 +5,7 @@ name = "compiler_builtins"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cast = { version = "0.2.0", optional = true }
|
cast = { version = "0.2.2", features = ["x128"], optional = true }
|
||||||
rand = { version = "0.3.15", optional = true }
|
rand = { version = "0.3.15", optional = true }
|
||||||
|
|
||||||
[build-dependencies.gcc]
|
[build-dependencies.gcc]
|
||||||
|
|
44
README.md
44
README.md
|
@ -141,22 +141,22 @@ features = ["c"]
|
||||||
- [x] divsi3.c
|
- [x] divsi3.c
|
||||||
- [ ] extendhfsf2.c
|
- [ ] extendhfsf2.c
|
||||||
- [ ] extendsfdf2.c
|
- [ ] extendsfdf2.c
|
||||||
- [ ] fixdfdi.c
|
- [x] fixdfdi.c
|
||||||
- [ ] fixdfsi.c
|
- [x] fixdfsi.c
|
||||||
- [ ] fixsfdi.c
|
- [x] fixsfdi.c
|
||||||
- [ ] fixsfsi.c
|
- [x] fixsfsi.c
|
||||||
- [ ] fixunsdfdi.c
|
- [x] fixunsdfdi.c
|
||||||
- [ ] fixunsdfsi.c
|
- [x] fixunsdfsi.c
|
||||||
- [ ] fixunssfdi.c
|
- [x] fixunssfdi.c
|
||||||
- [ ] fixunssfsi.c
|
- [x] fixunssfsi.c
|
||||||
- [ ] floatdidf.c
|
- [x] floatdidf.c
|
||||||
- [ ] floatdisf.c
|
- [ ] floatdisf.c
|
||||||
- [ ] floatsidf.c
|
- [x] floatsidf.c
|
||||||
- [ ] floatsisf.c
|
- [x] floatsisf.c
|
||||||
- [ ] floatundidf.c
|
- [x] floatundidf.c
|
||||||
- [ ] floatundisf.c
|
- [ ] floatundisf.c
|
||||||
- [ ] floatunsidf.c
|
- [x] floatunsidf.c
|
||||||
- [ ] floatunsisf.c
|
- [x] floatunsisf.c
|
||||||
- [ ] i386/ashldi3.S
|
- [ ] i386/ashldi3.S
|
||||||
- [ ] i386/ashrdi3.S
|
- [ ] i386/ashrdi3.S
|
||||||
- [ ] i386/chkstk.S
|
- [ ] i386/chkstk.S
|
||||||
|
@ -196,14 +196,14 @@ These builtins are needed to support 128-bit integers, which are in the process
|
||||||
- [x] ashlti3.c
|
- [x] ashlti3.c
|
||||||
- [x] ashrti3.c
|
- [x] ashrti3.c
|
||||||
- [x] divti3.c
|
- [x] divti3.c
|
||||||
- [ ] fixdfti.c
|
- [x] fixdfti.c
|
||||||
- [ ] fixsfti.c
|
- [x] fixsfti.c
|
||||||
- [ ] fixunsdfti.c
|
- [x] fixunsdfti.c
|
||||||
- [ ] fixunssfti.c
|
- [x] fixunssfti.c
|
||||||
- [ ] floattidf.c
|
- [x] floattidf.c
|
||||||
- [ ] floattisf.c
|
- [x] floattisf.c
|
||||||
- [ ] floatuntidf.c
|
- [x] floatuntidf.c
|
||||||
- [ ] floatuntisf.c
|
- [x] floatuntisf.c
|
||||||
- [x] lshrti3.c
|
- [x] lshrti3.c
|
||||||
- [x] modti3.c
|
- [x] modti3.c
|
||||||
- [x] muloti4.c
|
- [x] muloti4.c
|
||||||
|
|
529
build.rs
529
build.rs
|
@ -49,7 +49,7 @@ mod tests {
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{env, mem};
|
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;
|
use self::rand::Rng;
|
||||||
|
|
||||||
const NTESTS: usize = 10_000;
|
const NTESTS: usize = 10_000;
|
||||||
|
@ -74,16 +74,24 @@ mod tests {
|
||||||
Fixdfsi,
|
Fixdfsi,
|
||||||
Fixsfdi,
|
Fixsfdi,
|
||||||
Fixsfsi,
|
Fixsfsi,
|
||||||
|
Fixsfti,
|
||||||
|
Fixdfti,
|
||||||
Fixunsdfdi,
|
Fixunsdfdi,
|
||||||
Fixunsdfsi,
|
Fixunsdfsi,
|
||||||
Fixunssfdi,
|
Fixunssfdi,
|
||||||
Fixunssfsi,
|
Fixunssfsi,
|
||||||
|
Fixunssfti,
|
||||||
|
Fixunsdfti,
|
||||||
Floatdidf,
|
Floatdidf,
|
||||||
Floatsidf,
|
Floatsidf,
|
||||||
Floatsisf,
|
Floatsisf,
|
||||||
|
Floattisf,
|
||||||
|
Floattidf,
|
||||||
Floatundidf,
|
Floatundidf,
|
||||||
Floatunsidf,
|
Floatunsidf,
|
||||||
Floatunsisf,
|
Floatunsisf,
|
||||||
|
Floatuntisf,
|
||||||
|
Floatuntidf,
|
||||||
|
|
||||||
// float/pow.rs
|
// float/pow.rs
|
||||||
Powidf2,
|
Powidf2,
|
||||||
|
@ -1084,7 +1092,7 @@ static TEST_CASES: &[((u32,), i32)] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fixsfdi() {
|
fn fixsfsi() {
|
||||||
for &((a,), b) in TEST_CASES {
|
for &((a,), b) in TEST_CASES {
|
||||||
let b_ = __fixsfsi(mk_f32(a));
|
let b_ = __fixsfsi(mk_f32(a));
|
||||||
assert_eq!(((a,), b), ((a,), b_));
|
assert_eq!(((a,), b), ((a,), b_));
|
||||||
|
@ -1094,6 +1102,128 @@ fn fixsfdi() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
|
pub struct Fixsfti {
|
||||||
|
a: u32, // f32
|
||||||
|
b: i128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for Fixsfti {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"fixsfti"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<R>(rng: &mut R) -> Option<Self>
|
||||||
|
where
|
||||||
|
R: Rng,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let a = gen_f32(rng);
|
||||||
|
i128(a).ok().map(|b| Fixsfti { a: to_u32(a), b })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string(&self, buffer: &mut String) {
|
||||||
|
writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prologue() -> &'static str {
|
||||||
|
r#"
|
||||||
|
#[cfg(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test))]
|
||||||
|
use core::mem;
|
||||||
|
#[cfg(not(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test)))]
|
||||||
|
use std::mem;
|
||||||
|
use compiler_builtins::float::conv::__fixsfti;
|
||||||
|
|
||||||
|
fn mk_f32(x: u32) -> f32 {
|
||||||
|
unsafe { mem::transmute(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static TEST_CASES: &[((u32,), i128)] = &[
|
||||||
|
"#
|
||||||
|
}
|
||||||
|
|
||||||
|
fn epilogue() -> &'static str {
|
||||||
|
"
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fixsfti() {
|
||||||
|
for &((a,), b) in TEST_CASES {
|
||||||
|
let b_ = __fixsfti(mk_f32(a));
|
||||||
|
assert_eq!(((a,), b), ((a,), b_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
|
pub struct Fixdfti {
|
||||||
|
a: u64, // f64
|
||||||
|
b: i128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for Fixdfti {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"fixdfti"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<R>(rng: &mut R) -> Option<Self>
|
||||||
|
where
|
||||||
|
R: Rng,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let a = gen_f64(rng);
|
||||||
|
i128(a).ok().map(|b| Fixdfti { a: to_u64(a), b })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string(&self, buffer: &mut String) {
|
||||||
|
writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prologue() -> &'static str {
|
||||||
|
r#"
|
||||||
|
#[cfg(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test))]
|
||||||
|
use core::mem;
|
||||||
|
#[cfg(not(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test)))]
|
||||||
|
use std::mem;
|
||||||
|
use compiler_builtins::float::conv::__fixdfti;
|
||||||
|
|
||||||
|
fn mk_f64(x: u64) -> f64 {
|
||||||
|
unsafe { mem::transmute(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static TEST_CASES: &[((u64,), i128)] = &[
|
||||||
|
"#
|
||||||
|
}
|
||||||
|
|
||||||
|
fn epilogue() -> &'static str {
|
||||||
|
"
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fixdfti() {
|
||||||
|
for &((a,), b) in TEST_CASES {
|
||||||
|
let b_ = __fixdfti(mk_f64(a));
|
||||||
|
assert_eq!(((a,), b), ((a,), b_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq)]
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
pub struct Fixunsdfdi {
|
pub struct Fixunsdfdi {
|
||||||
a: u64, // f64
|
a: u64, // f64
|
||||||
|
@ -1338,6 +1468,128 @@ fn fixunssfsi() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
|
pub struct Fixunssfti {
|
||||||
|
a: u32, // f32
|
||||||
|
b: u128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for Fixunssfti {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"fixunssfti"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<R>(rng: &mut R) -> Option<Self>
|
||||||
|
where
|
||||||
|
R: Rng,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let a = gen_f32(rng);
|
||||||
|
u128(a).ok().map(|b| Fixunssfti { a: to_u32(a), b })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string(&self, buffer: &mut String) {
|
||||||
|
writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prologue() -> &'static str {
|
||||||
|
r#"
|
||||||
|
#[cfg(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test))]
|
||||||
|
use core::mem;
|
||||||
|
#[cfg(not(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test)))]
|
||||||
|
use std::mem;
|
||||||
|
use compiler_builtins::float::conv::__fixunssfti;
|
||||||
|
|
||||||
|
fn mk_f32(x: u32) -> f32 {
|
||||||
|
unsafe { mem::transmute(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static TEST_CASES: &[((u32,), u128)] = &[
|
||||||
|
"#
|
||||||
|
}
|
||||||
|
|
||||||
|
fn epilogue() -> &'static str {
|
||||||
|
"
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fixunssfti() {
|
||||||
|
for &((a,), b) in TEST_CASES {
|
||||||
|
let b_ = __fixunssfti(mk_f32(a));
|
||||||
|
assert_eq!(((a,), b), ((a,), b_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
|
pub struct Fixunsdfti {
|
||||||
|
a: u64, // f64
|
||||||
|
b: u128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for Fixunsdfti {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"fixunsdfti"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<R>(rng: &mut R) -> Option<Self>
|
||||||
|
where
|
||||||
|
R: Rng,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let a = gen_f64(rng);
|
||||||
|
u128(a).ok().map(|b| Fixunsdfti { a: to_u64(a), b })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string(&self, buffer: &mut String) {
|
||||||
|
writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prologue() -> &'static str {
|
||||||
|
r#"
|
||||||
|
#[cfg(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test))]
|
||||||
|
use core::mem;
|
||||||
|
#[cfg(not(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test)))]
|
||||||
|
use std::mem;
|
||||||
|
use compiler_builtins::float::conv::__fixunsdfti;
|
||||||
|
|
||||||
|
fn mk_f64(x: u64) -> f64 {
|
||||||
|
unsafe { mem::transmute(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static TEST_CASES: &[((u64,), u128)] = &[
|
||||||
|
"#
|
||||||
|
}
|
||||||
|
|
||||||
|
fn epilogue() -> &'static str {
|
||||||
|
"
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fixunsdfti() {
|
||||||
|
for &((a,), b) in TEST_CASES {
|
||||||
|
let b_ = __fixunsdfti(mk_f64(a));
|
||||||
|
assert_eq!(((a,), b), ((a,), b_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq)]
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
pub struct Floatdidf {
|
pub struct Floatdidf {
|
||||||
a: i64,
|
a: i64,
|
||||||
|
@ -1536,6 +1788,140 @@ fn floatsisf() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
|
pub struct Floattisf {
|
||||||
|
a: i128,
|
||||||
|
b: u32, // f32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for Floattisf {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"floattisf"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<R>(rng: &mut R) -> Option<Self>
|
||||||
|
where
|
||||||
|
R: Rng,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let a = gen_i128(rng);
|
||||||
|
Some(
|
||||||
|
Floattisf {
|
||||||
|
a,
|
||||||
|
b: to_u32(f32(a)),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string(&self, buffer: &mut String) {
|
||||||
|
writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prologue() -> &'static str {
|
||||||
|
r#"
|
||||||
|
#[cfg(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test))]
|
||||||
|
use core::mem;
|
||||||
|
#[cfg(not(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test)))]
|
||||||
|
use std::mem;
|
||||||
|
use compiler_builtins::float::conv::__floattisf;
|
||||||
|
|
||||||
|
fn to_u32(x: f32) -> u32 {
|
||||||
|
unsafe { mem::transmute(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static TEST_CASES: &[((i128,), u32)] = &[
|
||||||
|
"#
|
||||||
|
}
|
||||||
|
|
||||||
|
fn epilogue() -> &'static str {
|
||||||
|
"
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn floattisf() {
|
||||||
|
for &((a,), b) in TEST_CASES {
|
||||||
|
let b_ = __floattisf(a);
|
||||||
|
assert_eq!(((a,), b), ((a,), to_u32(b_)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
|
pub struct Floattidf {
|
||||||
|
a: i128,
|
||||||
|
b: u64, // f64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for Floattidf {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"floattidf"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<R>(rng: &mut R) -> Option<Self>
|
||||||
|
where
|
||||||
|
R: Rng,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let a = gen_i128(rng);
|
||||||
|
Some(
|
||||||
|
Floattidf {
|
||||||
|
a,
|
||||||
|
b: to_u64(f64(a)),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string(&self, buffer: &mut String) {
|
||||||
|
writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prologue() -> &'static str {
|
||||||
|
r#"
|
||||||
|
#[cfg(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test))]
|
||||||
|
use core::mem;
|
||||||
|
#[cfg(not(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test)))]
|
||||||
|
use std::mem;
|
||||||
|
use compiler_builtins::float::conv::__floattidf;
|
||||||
|
|
||||||
|
fn to_u64(x: f64) -> u64 {
|
||||||
|
unsafe { mem::transmute(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static TEST_CASES: &[((i128,), u64)] = &[
|
||||||
|
"#
|
||||||
|
}
|
||||||
|
|
||||||
|
fn epilogue() -> &'static str {
|
||||||
|
"
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn floattidf() {
|
||||||
|
for &((a,), b) in TEST_CASES {
|
||||||
|
let b_ = __floattidf(a);
|
||||||
|
let g_b = to_u64(b_);
|
||||||
|
let diff = if g_b > b { g_b - b } else { b - g_b };
|
||||||
|
assert_eq!(((a,), b, g_b, true), ((a,), b, g_b, diff <= 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq)]
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
pub struct Floatundidf {
|
pub struct Floatundidf {
|
||||||
a: u64,
|
a: u64,
|
||||||
|
@ -1734,6 +2120,141 @@ fn floatunsisf() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
|
pub struct Floatuntisf {
|
||||||
|
a: u128,
|
||||||
|
b: u32, // f32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for Floatuntisf {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"floatuntisf"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<R>(rng: &mut R) -> Option<Self>
|
||||||
|
where
|
||||||
|
R: Rng,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let a = gen_u128(rng);
|
||||||
|
let f_a = f32(a);
|
||||||
|
f_a.ok().map(|f| {
|
||||||
|
Floatuntisf {
|
||||||
|
a,
|
||||||
|
b: to_u32(f),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string(&self, buffer: &mut String) {
|
||||||
|
writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prologue() -> &'static str {
|
||||||
|
r#"
|
||||||
|
#[cfg(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test))]
|
||||||
|
use core::mem;
|
||||||
|
#[cfg(not(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test)))]
|
||||||
|
use std::mem;
|
||||||
|
use compiler_builtins::float::conv::__floatuntisf;
|
||||||
|
|
||||||
|
fn to_u32(x: f32) -> u32 {
|
||||||
|
unsafe { mem::transmute(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static TEST_CASES: &[((u128,), u32)] = &[
|
||||||
|
"#
|
||||||
|
}
|
||||||
|
|
||||||
|
fn epilogue() -> &'static str {
|
||||||
|
"
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn floatuntisf() {
|
||||||
|
for &((a,), b) in TEST_CASES {
|
||||||
|
let b_ = __floatuntisf(a);
|
||||||
|
assert_eq!(((a,), b), ((a,), to_u32(b_)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
|
pub struct Floatuntidf {
|
||||||
|
a: u128,
|
||||||
|
b: u64, // f64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestCase for Floatuntidf {
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"floatuntidf"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<R>(rng: &mut R) -> Option<Self>
|
||||||
|
where
|
||||||
|
R: Rng,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let a = gen_u128(rng);
|
||||||
|
Some(
|
||||||
|
Floatuntidf {
|
||||||
|
a,
|
||||||
|
b: to_u64(f64(a)),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string(&self, buffer: &mut String) {
|
||||||
|
writeln!(buffer, "(({a},), {b}),", a = self.a, b = self.b).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prologue() -> &'static str {
|
||||||
|
r#"
|
||||||
|
#[cfg(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test))]
|
||||||
|
use core::mem;
|
||||||
|
#[cfg(not(all(target_arch = "arm",
|
||||||
|
not(any(target_env = "gnu", target_env = "musl")),
|
||||||
|
target_os = "linux",
|
||||||
|
test)))]
|
||||||
|
use std::mem;
|
||||||
|
use compiler_builtins::float::conv::__floatuntidf;
|
||||||
|
|
||||||
|
fn to_u64(x: f64) -> u64 {
|
||||||
|
unsafe { mem::transmute(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
static TEST_CASES: &[((u128,), u64)] = &[
|
||||||
|
"#
|
||||||
|
}
|
||||||
|
|
||||||
|
fn epilogue() -> &'static str {
|
||||||
|
"
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn floatuntidf() {
|
||||||
|
for &((a,), b) in TEST_CASES {
|
||||||
|
let b_ = __floatuntidf(a);
|
||||||
|
let g_b = to_u64(b_);
|
||||||
|
let diff = if g_b > b { g_b - b } else { b - g_b };
|
||||||
|
assert_eq!(((a,), b, g_b, true), ((a,), b, g_b, diff <= 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq)]
|
#[derive(Eq, Hash, PartialEq)]
|
||||||
pub struct Moddi3 {
|
pub struct Moddi3 {
|
||||||
a: i64,
|
a: i64,
|
||||||
|
@ -3417,7 +3938,9 @@ macro_rules! panic {
|
||||||
|
|
||||||
let rng = &mut rand::thread_rng();
|
let rng = &mut rand::thread_rng();
|
||||||
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
let out_file = out_dir.join(format!("{}.rs", T::name()));
|
let out_file_name = format!("{}.rs", T::name());
|
||||||
|
let out_file = out_dir.join(&out_file_name);
|
||||||
|
println!("Generating {}", out_file_name);
|
||||||
let contents = mk_tests::<T, _>(NTESTS, rng);
|
let contents = mk_tests::<T, _>(NTESTS, rng);
|
||||||
|
|
||||||
File::create(out_file)
|
File::create(out_file)
|
||||||
|
|
|
@ -12,10 +12,13 @@ macro_rules! fp_overflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! fp_convert {
|
macro_rules! int_to_float {
|
||||||
($intrinsic:ident: $ity:ty, $fty:ty) => {
|
($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 {
|
if i == 0 {
|
||||||
return 0.0
|
return 0.0
|
||||||
}
|
}
|
||||||
|
@ -82,12 +85,25 @@ macro_rules! fp_convert {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_convert!(__floatsisf: i32, f32);
|
macro_rules! int_to_float_unadj_on_win {
|
||||||
fp_convert!(__floatsidf: i32, f64);
|
($intrinsic:ident: $ity:ty, $fty:ty) => {
|
||||||
fp_convert!(__floatdidf: i64, f64);
|
#[cfg(all(windows, target_pointer_width="64"))]
|
||||||
fp_convert!(__floatunsisf: u32, f32);
|
int_to_float!($intrinsic: $ity, $fty, "unadjusted");
|
||||||
fp_convert!(__floatunsidf: u32, f64);
|
#[cfg(not(all(windows, target_pointer_width="64")))]
|
||||||
fp_convert!(__floatundidf: u64, f64);
|
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)]
|
#[derive(PartialEq, Debug)]
|
||||||
enum Sign {
|
enum Sign {
|
||||||
|
@ -95,9 +111,12 @@ enum Sign {
|
||||||
Negative
|
Negative
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! fp_fix {
|
macro_rules! float_to_int {
|
||||||
($intrinsic:ident: $fty:ty, $ity:ty) => {
|
($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_min = <$ity>::min_value();
|
||||||
let fixint_max = <$ity>::max_value();
|
let fixint_max = <$ity>::max_value();
|
||||||
let fixint_bits = <$ity>::bits() as usize;
|
let fixint_bits = <$ity>::bits() as usize;
|
||||||
|
@ -147,12 +166,25 @@ macro_rules! fp_fix {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_fix!(__fixsfsi: f32, i32);
|
macro_rules! float_to_int_unadj_on_win {
|
||||||
fp_fix!(__fixsfdi: f32, i64);
|
($intrinsic:ident: $fty:ty, $ity:ty) => {
|
||||||
fp_fix!(__fixdfsi: f64, i32);
|
#[cfg(all(windows, target_pointer_width="64"))]
|
||||||
fp_fix!(__fixdfdi: f64, i64);
|
float_to_int!($intrinsic: $fty, $ity, "unadjusted");
|
||||||
|
#[cfg(not(all(windows, target_pointer_width="64")))]
|
||||||
|
float_to_int!($intrinsic: $fty, $ity, "C");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fp_fix!(__fixunssfsi: f32, u32);
|
float_to_int!(__fixsfsi: f32, i32);
|
||||||
fp_fix!(__fixunssfdi: f32, u64);
|
float_to_int!(__fixsfdi: f32, i64);
|
||||||
fp_fix!(__fixunsdfsi: f64, u32);
|
float_to_int_unadj_on_win!(__fixsfti: f32, i128);
|
||||||
fp_fix!(__fixunsdfdi: f64, u64);
|
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);
|
||||||
|
|
|
@ -63,7 +63,7 @@ macro_rules! int_impl {
|
||||||
|
|
||||||
fn extract_sign(self) -> (bool, $uty) {
|
fn extract_sign(self) -> (bool, $uty) {
|
||||||
if self < 0 {
|
if self < 0 {
|
||||||
(true, !(self as $uty) + 1)
|
(true, (!(self as $uty)).wrapping_add(1))
|
||||||
} else {
|
} else {
|
||||||
(false, self as $uty)
|
(false, self as $uty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
|
@ -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"));
|
|
@ -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"));
|
|
@ -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"));
|
|
@ -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"));
|
|
@ -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"));
|
|
@ -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"));
|
|
@ -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"));
|
Loading…
Reference in New Issue