compiler-builtins-zynq/src/float/mod.rs

165 lines
4.8 KiB
Rust
Raw Normal View History

2016-08-18 04:51:37 +08:00
use core::mem;
pub mod add;
/// Trait for some basic operations on floats
pub trait Float: Sized + Copy {
2016-08-18 04:51:37 +08:00
/// A uint of the same with as the float
type Int;
2016-08-18 04:51:37 +08:00
/// Returns the bitwidth of the float type
fn bits() -> u32;
/// Returns the bitwidth of the exponent
fn exponent_bits() -> u32;
2016-08-18 04:51:37 +08:00
/// Returns the bitwidth of the significand
fn significand_bits() -> u32;
2016-09-30 09:48:33 +08:00
/// Returns a mask for the sign bit of `self`
fn sign_mask() -> Self::Int;
2016-08-18 04:51:37 +08:00
2016-09-30 09:48:33 +08:00
/// Returns a mask for the exponent portion of `self`
fn exponent_mask() -> Self::Int;
2016-09-30 09:48:33 +08:00
/// Returns a mask for the significand portion of `self`
fn significand_mask() -> Self::Int;
2016-08-18 04:51:37 +08:00
/// Returns the sign bit of `self`
fn sign(self) -> bool;
/// Returns the exponent portion of `self`, shifted to the right
fn exponent(self) -> Self::Int;
/// Returns the significand portion of `self`
fn significand(self) -> Self::Int;
2016-09-30 09:48:33 +08:00
/// Returns `self` transmuted to `Self::Int`
fn repr(self) -> Self::Int;
#[cfg(test)]
/// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
/// represented in multiple different ways. This method returns `true` if two NaNs are
/// compared.
fn eq_repr(self, rhs: Self) -> bool;
/// Returns a `Self::Int` transmuted back to `Self`
fn from_repr(a: Self::Int) -> Self;
/// Constructs a `Self` from its parts
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self;
2016-08-18 04:51:37 +08:00
/// Returns (normalized exponent, normalized significand)
fn normalize(significand: Self::Int) -> (i32, Self::Int);
}
impl Float for f32 {
type Int = u32;
fn bits() -> u32 {
32
}
fn exponent_bits() -> u32 {
8
}
2016-08-18 04:51:37 +08:00
fn significand_bits() -> u32 {
23
}
2016-09-30 09:48:33 +08:00
fn sign_mask() -> Self::Int {
1 << (Self::bits() - 1)
}
fn exponent_mask() -> Self::Int {
((1 << Self::exponent_bits()) - 1) << Self::significand_bits()
}
fn significand_mask() -> Self::Int {
(1 << Self::significand_bits()) - 1
}
2016-08-18 04:51:37 +08:00
fn repr(self) -> Self::Int {
unsafe { mem::transmute(self) }
}
#[cfg(test)]
fn eq_repr(self, rhs: Self) -> bool {
if self.is_nan() && rhs.is_nan() {
true
} else {
self.repr() == rhs.repr()
}
}
2016-08-18 04:51:37 +08:00
fn from_repr(a: Self::Int) -> Self {
unsafe { mem::transmute(a) }
}
2016-09-30 09:48:33 +08:00
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
Self::from_repr(((sign as Self::Int) << (Self::bits() - 1)) |
exponent & Self::exponent_mask() |
significand & Self::significand_mask())
}
fn sign(self) -> bool {
2016-09-30 09:48:33 +08:00
(self.repr() & Self::sign_mask()) != 0
}
fn exponent(self) -> Self::Int {
2016-09-30 09:48:33 +08:00
self.repr() >> Self::significand_bits() & Self::exponent_mask()
}
fn significand(self) -> Self::Int {
2016-09-30 09:48:33 +08:00
self.repr() & Self::significand_mask()
}
2016-08-18 04:51:37 +08:00
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
let shift = significand.leading_zeros()
.wrapping_sub((1u32 << Self::significand_bits()).leading_zeros());
(1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
}
}
impl Float for f64 {
type Int = u64;
fn bits() -> u32 {
64
}
fn exponent_bits() -> u32 {
11
}
2016-08-18 04:51:37 +08:00
fn significand_bits() -> u32 {
52
}
2016-09-30 09:48:33 +08:00
fn sign_mask() -> Self::Int {
1 << (Self::bits() - 1)
}
fn exponent_mask() -> Self::Int {
((1 << Self::exponent_bits()) - 1) << Self::significand_bits()
}
fn significand_mask() -> Self::Int {
(1 << Self::significand_bits()) - 1
}
2016-08-18 04:51:37 +08:00
fn repr(self) -> Self::Int {
unsafe { mem::transmute(self) }
}
#[cfg(test)]
fn eq_repr(self, rhs: Self) -> bool {
if self.is_nan() && rhs.is_nan() {
true
} else {
self.repr() == rhs.repr()
}
}
2016-08-18 04:51:37 +08:00
fn from_repr(a: Self::Int) -> Self {
unsafe { mem::transmute(a) }
}
2016-09-30 09:48:33 +08:00
fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
Self::from_repr(((sign as Self::Int) << (Self::bits() - 1)) |
exponent & Self::exponent_mask() |
significand & Self::significand_mask())
}
fn sign(self) -> bool {
2016-09-30 09:48:33 +08:00
(self.repr() & Self::sign_mask()) != 0
}
fn exponent(self) -> Self::Int {
2016-09-30 09:48:33 +08:00
self.repr() >> Self::significand_bits() & Self::exponent_mask()
}
fn significand(self) -> Self::Int {
2016-09-30 09:48:33 +08:00
self.repr() & Self::significand_mask()
}
2016-08-18 04:51:37 +08:00
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
let shift = significand.leading_zeros()
.wrapping_sub((1u64 << Self::significand_bits()).leading_zeros());
(1i32.wrapping_sub(shift as i32), significand << shift as Self::Int)
}
}