From 89a274195680d3ea6a2b442ff633b81ccf60bbe4 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 11 Sep 2023 11:19:34 +0200 Subject: [PATCH] Revert "Remove limb_width32 and limb_width64 features" This reverts commit c754f0344b61bf20fe76c205fd8d7a3d46138a96. --- build.rs | 36 ++++++++++++++++ src/lexical/math.rs | 86 +++++++++++-------------------------- src/lexical/mod.rs | 9 +++- src/lexical/small_powers.rs | 3 ++ tests/lexical/math.rs | 14 +----- 5 files changed, 73 insertions(+), 75 deletions(-) create mode 100644 build.rs diff --git a/build.rs b/build.rs new file mode 100644 index 000000000..bc2878cf2 --- /dev/null +++ b/build.rs @@ -0,0 +1,36 @@ +use std::env; +use std::process::Command; +use std::str::{self, FromStr}; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + + // Decide ideal limb width for arithmetic in the float parser. Refer to + // src/lexical/math.rs for where this has an effect. + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + match target_arch.as_str() { + "aarch64" | "mips64" | "powerpc64" | "x86_64" => { + println!("cargo:rustc-cfg=limb_width_64"); + } + _ => { + println!("cargo:rustc-cfg=limb_width_32"); + } + } + + let minor = match rustc_minor_version() { + Some(minor) => minor, + None => return, + }; +} + +fn rustc_minor_version() -> Option { + let rustc = env::var_os("RUSTC")?; + let output = Command::new(rustc).arg("--version").output().ok()?; + let version = str::from_utf8(&output.stdout).ok()?; + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + let next = pieces.next()?; + u32::from_str(next).ok() +} diff --git a/src/lexical/math.rs b/src/lexical/math.rs index 3c0ea0c34..d7122bffa 100644 --- a/src/lexical/math.rs +++ b/src/lexical/math.rs @@ -6,6 +6,7 @@ //! buffers, so for a `vec![0, 1, 2, 3]`, `3` is the most significant limb, //! and `0` is the least significant limb. +use super::large_powers; use super::num::*; use super::small_powers::*; use alloc::vec::Vec; @@ -35,58 +36,31 @@ use core::{cmp, iter, mem}; // requiring software emulation. // sparc64 (`UMUL` only supported double-word arguments). -#[doc(hidden)] -pub trait LimbConfig { - type Limb: 'static; - type Wide: 'static; - const POW5_LIMB: &'static [Self::Limb]; - const POW10_LIMB: &'static [Self::Limb]; - const LARGE_POWERS: &'static [&'static [Self::Limb]]; -} - // 32-BIT LIMB -#[doc(hidden)] -pub struct LimbConfig32; - -impl LimbConfig for LimbConfig32 { - type Limb = u32; - type Wide = u64; - const POW5_LIMB: &'static [Self::Limb] = &POW5_32; - const POW10_LIMB: &'static [Self::Limb] = &POW10_32; - const LARGE_POWERS: &'static [&'static [Self::Limb]] = &super::large_powers32::POW5; -} +#[cfg(limb_width_32)] +pub type Limb = u32; + +#[cfg(limb_width_32)] +pub const POW5_LIMB: &[Limb] = &POW5_32; + +#[cfg(limb_width_32)] +pub const POW10_LIMB: &[Limb] = &POW10_32; + +#[cfg(limb_width_32)] +type Wide = u64; // 64-BIT LIMB -#[doc(hidden)] -pub struct LimbConfig64; -impl LimbConfig for LimbConfig64 { - type Limb = u64; - type Wide = u128; - const POW5_LIMB: &'static [Self::Limb] = &POW5_64; - const POW10_LIMB: &'static [Self::Limb] = &POW10_64; - const LARGE_POWERS: &'static [&'static [Self::Limb]] = &super::large_powers64::POW5; -} +#[cfg(limb_width_64)] +pub type Limb = u64; + +#[cfg(limb_width_64)] +pub const POW5_LIMB: &[Limb] = &POW5_64; + +#[cfg(limb_width_64)] +pub const POW10_LIMB: &[Limb] = &POW10_64; -#[cfg(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "powerpc64", - target_arch = "x86_64" -))] -type PlatformLimbConfig = LimbConfig64; -#[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "powerpc64", - target_arch = "x86_64" -)))] -type PlatformLimbConfig = LimbConfig32; - -pub type Limb = ::Limb; -type Wide = ::Wide; -pub const POW5_LIMB: &[Limb] = PlatformLimbConfig::POW5_LIMB; -pub const POW10_LIMB: &[Limb] = PlatformLimbConfig::POW10_LIMB; -const LARGE_POWERS: &'static [&'static [Limb]] = PlatformLimbConfig::LARGE_POWERS; +#[cfg(limb_width_64)] +type Wide = u128; /// Cast to limb type. #[inline] @@ -105,24 +79,14 @@ fn as_wide(t: T) -> Wide { /// Split u64 into limbs, in little-endian order. #[inline] -#[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "powerpc64", - target_arch = "x86_64" -)))] +#[cfg(limb_width_32)] fn split_u64(x: u64) -> [Limb; 2] { [as_limb(x), as_limb(x >> 32)] } /// Split u64 into limbs, in little-endian order. #[inline] -#[cfg(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "powerpc64", - target_arch = "x86_64" -))] +#[cfg(limb_width_64)] fn split_u64(x: u64) -> [Limb; 1] { [as_limb(x)] } @@ -427,7 +391,7 @@ mod small { use super::large::KARATSUBA_CUTOFF; let small_powers = POW5_LIMB; - let large_powers = LARGE_POWERS; + let large_powers = large_powers::POW5; if n == 0 { // No exponent, just return. diff --git a/src/lexical/mod.rs b/src/lexical/mod.rs index 22784144a..b1a45e218 100644 --- a/src/lexical/mod.rs +++ b/src/lexical/mod.rs @@ -20,8 +20,7 @@ mod digit; mod errors; pub(crate) mod exponent; pub(crate) mod float; -mod large_powers32; -mod large_powers64; +mod large_powers; pub(crate) mod math; pub(crate) mod num; pub(crate) mod parse; @@ -29,5 +28,11 @@ pub(crate) mod rounding; mod shift; mod small_powers; +#[cfg(limb_width_32)] +mod large_powers32; + +#[cfg(limb_width_64)] +mod large_powers64; + // API pub use self::parse::{parse_concise_float, parse_truncated_float}; diff --git a/src/lexical/small_powers.rs b/src/lexical/small_powers.rs index ac3f3aad7..219d82611 100644 --- a/src/lexical/small_powers.rs +++ b/src/lexical/small_powers.rs @@ -3,16 +3,19 @@ //! Pre-computed small powers. // 32 BIT +#[cfg(limb_width_32)] pub(crate) const POW5_32: [u32; 14] = [ 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125, ]; +#[cfg(limb_width_32)] pub(crate) const POW10_32: [u32; 10] = [ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, ]; // 64 BIT +#[cfg(limb_width_64)] pub(crate) const POW5_64: [u64; 28] = [ 1, 5, diff --git a/tests/lexical/math.rs b/tests/lexical/math.rs index ce8ae502d..79d3ef3ee 100644 --- a/tests/lexical/math.rs +++ b/tests/lexical/math.rs @@ -18,22 +18,12 @@ impl Math for Bigint { } } -#[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "powerpc64", - target_arch = "x86_64" -)))] +#[cfg(limb_width_32)] pub(crate) fn from_u32(x: &[u32]) -> Vec { x.iter().cloned().collect() } -#[cfg(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "powerpc64", - target_arch = "x86_64" -))] +#[cfg(limb_width_64)] pub(crate) fn from_u32(x: &[u32]) -> Vec { let mut v = Vec::::default(); for xi in x.chunks(2) {