Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions astro-float-num/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ serde = { version = "1.0.147", optional = true }
rand = { version = "0.8.5", optional = true }
lazy_static = { version = "1.4.0", default-features = false, features = [] }
itertools = { version = "0.10.3", default-features = false, features = [] }
cfg-if = "1.0.0"

[features]
default = ["std", "random", "serde"]
Expand Down
57 changes: 24 additions & 33 deletions astro-float-num/src/common/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Auxiliary functions.

use crate::{
defs::{Word, WORD_BIT_SIZE, WORD_MAX, WORD_SIGNIFICANT_BIT},
defs::{DoubleWord, Word, WORD_BASE, WORD_BIT_SIZE, WORD_MAX, WORD_SIGNIFICANT_BIT},
RoundingMode,
};

Expand Down Expand Up @@ -117,32 +117,28 @@ pub fn calc_sqrt_cost(p: usize, cost_mul: usize, cost_add: usize) -> usize {

#[inline(always)]
pub fn add_carry(a: Word, b: Word, c: Word, r: &mut Word) -> Word {
// Using
#[cfg(target_arch = "x86_64")]
{
// platform-specific operation
unsafe { core::arch::x86_64::_addcarry_u64(c as u8, a, b, r) as Word }
return unsafe { core::arch::x86_64::_addcarry_u64(c as u8, a, b, r) as Word };
}

#[cfg(target_arch = "x86")]
{
// platform-specific operation
unsafe { core::arch::x86::_addcarry_u32(c as u8, a, b, r) as Word }
return unsafe { core::arch::x86::_addcarry_u32(c as u8, a, b, r) as Word };
}

#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
{
use crate::defs::DoubleWord;
use crate::defs::WORD_BASE;

let mut s = c as DoubleWord + a as DoubleWord + b as DoubleWord;
if s >= WORD_BASE {
s -= WORD_BASE;
*r = s as Word;
1
} else {
*r = s as Word;
0
}
#[allow(unreachable_code)] // not used on x86
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for marking the code unreachable? Wouldn't it be better to keep it as it was before, since the code could be reachable for architectures different from x86, x86_64?

let mut s = c as DoubleWord + a as DoubleWord + b as DoubleWord;
if s >= WORD_BASE {
s -= WORD_BASE;
*r = s as Word;
1
} else {
*r = s as Word;
0
}
}

Expand All @@ -151,30 +147,25 @@ pub fn sub_borrow(a: Word, b: Word, c: Word, r: &mut Word) -> Word {
#[cfg(target_arch = "x86_64")]
{
// platform-specific operation
unsafe { core::arch::x86_64::_subborrow_u64(c as u8, a, b, r) as Word }
return unsafe { core::arch::x86_64::_subborrow_u64(c as u8, a, b, r) as Word };
}

#[cfg(target_arch = "x86")]
{
// platform-specific operation
unsafe { core::arch::x86::_subborrow_u32(c as u8, a, b, r) as Word }
return unsafe { core::arch::x86::_subborrow_u32(c as u8, a, b, r) as Word };
}

#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
{
use crate::defs::DoubleWord;
use crate::defs::WORD_BASE;
#[allow(unreachable_code)] // not used on x86
let v1 = a as DoubleWord;
let v2 = b as DoubleWord + c as DoubleWord;

let v1 = a as DoubleWord;
let v2 = b as DoubleWord + c as DoubleWord;

if v1 < v2 {
*r = (v1 + WORD_BASE - v2) as Word;
1
} else {
*r = (v1 - v2) as Word;
0
}
if v1 < v2 {
*r = (v1 + WORD_BASE - v2) as Word;
1
} else {
*r = (v1 - v2) as Word;
0
}
}

Expand Down
5 changes: 2 additions & 3 deletions astro-float-num/src/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ impl BigFloatNumber {
}
}

#[cfg(target_arch = "x86")]
if e < EXPONENT_MIN || e > EXPONENT_MAX {
return Err(Error::InvalidArgument);
}
Expand Down Expand Up @@ -830,7 +829,7 @@ mod tests {
let n = BigFloatNumber::from_f64(64, -83.591552734375).unwrap();
assert_eq!(n.cmp(&g), 0);

#[cfg(target_arch = "x86")]
#[cfg(not(target_pointer_width = "64"))]
{
let n = BigFloatNumber::from_raw_parts(
&[2576980377, 2576980377, 2576980377],
Expand Down Expand Up @@ -891,7 +890,7 @@ mod tests {
assert!(g.cmp(&n) == 0);
}

#[cfg(not(target_arch = "x86"))]
#[cfg(target_pointer_width = "64")]
{
let n = BigFloatNumber::from_raw_parts(
&[0x9999999999999999, 0x9999999999999999, 0x9999999999999999],
Expand Down
58 changes: 27 additions & 31 deletions astro-float-num/src/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,44 @@ use std::collections::TryReserveError;
#[cfg(not(feature = "std"))]
use alloc::collections::TryReserveError;

/// A word.
#[cfg(not(target_arch = "x86"))]
pub type Word = u64;
cfg_if::cfg_if! {
if #[cfg(target_pointer_width = "64")] {
/// A word.
pub type Word = u64;

/// Doubled word.
#[cfg(not(target_arch = "x86"))]
pub type DoubleWord = u128;
/// Doubled word.
pub type DoubleWord = u128;

/// Word with sign.
#[cfg(not(target_arch = "x86"))]
pub type SignedWord = i128;
/// Word with sign.
pub type SignedWord = i128;
} else {
/// A word.
pub type Word = u32;

/// A word.
#[cfg(target_arch = "x86")]
pub type Word = u32;
/// Doubled word.
pub type DoubleWord = u64;

/// Doubled word.
#[cfg(target_arch = "x86")]
pub type DoubleWord = u64;

/// Word with sign.
#[cfg(target_arch = "x86")]
pub type SignedWord = i64;
/// Word with sign.
pub type SignedWord = i64;
}
}

/// An exponent.
pub type Exponent = i32;

/// Maximum exponent value.
#[cfg(not(target_arch = "x86"))]
pub const EXPONENT_MAX: Exponent = Exponent::MAX;

/// Maximum exponent value.
#[cfg(target_arch = "x86")]
pub const EXPONENT_MAX: Exponent = Exponent::MAX / 4;

/// Minimum exponent value.
#[cfg(not(target_arch = "x86"))]
pub const EXPONENT_MIN: Exponent = Exponent::MIN;
pub const EXPONENT_MAX: Exponent = if cfg!(target_pointer_width = "64") {
Exponent::MAX
} else {
Exponent::MAX / 4
};

/// Minimum exponent value.
#[cfg(target_arch = "x86")]
pub const EXPONENT_MIN: Exponent = Exponent::MIN / 4;
pub const EXPONENT_MIN: Exponent = if cfg!(target_pointer_width = "64") {
Exponent::MIN
} else {
Exponent::MIN / 4
};

/// Maximum value of a word.
pub const WORD_MAX: Word = Word::MAX;
Expand Down
31 changes: 10 additions & 21 deletions astro-float-num/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2158,16 +2158,10 @@ mod tests {

let d1 = ONE.clone();
assert!(d1.exponent() == Some(1));
let words: &[Word] = {
#[cfg(not(target_arch = "x86"))]
{
&[0, 0x8000000000000000]
}
#[cfg(target_arch = "x86")]
{
&[0, 0, 0, 0x80000000]
}
};
#[cfg(target_pointer_width = "64")]
let words: &[Word] = &[0, 0x8000000000000000];
#[cfg(not(target_pointer_width = "64"))]
let words: &[Word] = &[0, 0, 0, 0x80000000];

assert!(d1.mantissa_digits() == Some(words));
assert!(d1.mantissa_max_bit_len() == Some(DEFAULT_P));
Expand Down Expand Up @@ -2473,22 +2467,17 @@ mod rand_tests {

use super::*;
use crate::defs::EXPONENT_MAX;
use crate::defs::EXPONENT_MIN;

#[test]
fn test_rand() {
for _ in 0..1000 {
let p = rand::random::<usize>() % 1000 + DEFAULT_P;
let exp_from;
#[cfg(not(target_arch = "x86"))]
{
exp_from = rand::random::<Exponent>().abs();
}
#[cfg(target_arch = "x86")]
{
use crate::defs::EXPONENT_MIN;
exp_from =
rand::random::<Exponent>().abs() % (EXPONENT_MAX - EXPONENT_MIN) + EXPONENT_MIN;
}
let exp_from = if cfg!(target_pointer_width = "64") {
rand::random::<Exponent>().abs()
} else {
rand::random::<Exponent>().abs() % (EXPONENT_MAX - EXPONENT_MIN) + EXPONENT_MIN
};
let exp_shift = if EXPONENT_MAX > exp_from {
rand::random::<Exponent>().abs()
% (EXPONENT_MAX as isize - exp_from as isize) as Exponent
Expand Down
10 changes: 4 additions & 6 deletions astro-float-num/src/mantissa/mantissa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,12 +717,11 @@ impl Mantissa {
let nd = m.len() - size_of::<u64>() / size_of::<Word>();
m[..nd].fill(0);

#[cfg(not(target_arch = "x86"))]
#[cfg(target_pointer_width = "64")]
{
m[nd] = u;
}

#[cfg(target_arch = "x86")]
#[cfg(not(target_pointer_width = "64"))]
{
let mut u = u;
for v in &mut m[nd..] {
Expand Down Expand Up @@ -764,12 +763,11 @@ impl Mantissa {

#[cfg(test)]
pub fn to_u64(&self) -> u64 {
#[cfg(not(target_arch = "x86"))]
#[cfg(target_pointer_width = "64")]
{
self.m[self.m.len() - 1]
}

#[cfg(target_arch = "x86")]
#[cfg(not(target_pointer_width = "64"))]
{
let mut ret: u64 = 0;
let nd = size_of::<u64>() / size_of::<Word>();
Expand Down
Loading