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