Skip to content

Commit

Permalink
Merge pull request #1183 from serde-rs/arithmetic
Browse files Browse the repository at this point in the history
Unify chunk size choice between float and string parsing
  • Loading branch information
dtolnay authored Aug 23, 2024
2 parents fec0376 + f268173 commit 4b1048d
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 44 deletions.
34 changes: 22 additions & 12 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@ use std::env;
fn main() {
println!("cargo:rerun-if-changed=build.rs");

println!("cargo:rustc-check-cfg=cfg(limb_width_32)");
println!("cargo:rustc-check-cfg=cfg(limb_width_64)");
println!("cargo:rustc-check-cfg=cfg(arithmetic32)");
println!("cargo:rustc-check-cfg=cfg(arithmetic64)");

// 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" | "loongarch64" => {
println!("cargo:rustc-cfg=limb_width_64");
}
_ => {
println!("cargo:rustc-cfg=limb_width_32");
}
// Decide ideal limb width for arithmetic in the float parser and string
// parser.
let target_arch = env::var_os("CARGO_CFG_TARGET_ARCH").unwrap();
let target_pointer_width = env::var_os("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap();
if target_arch == "aarch64"
|| target_arch == "loongarch64"
|| target_arch == "mips64"
|| target_arch == "powerpc64"
|| target_arch == "wasm32"
|| target_arch == "x86_64"
|| target_pointer_width == "64"
{
// The above list of architectures are ones that have native support for
// 64-bit arithmetic, but which have some targets using a smaller
// pointer width. Examples include aarch64-unknown-linux-gnu_ilp32 and
// x86_64-unknown-linux-gnux32. So our choice of limb width is not
// equivalent to using usize everywhere.
println!("cargo:rustc-cfg=arithmetic64");
} else {
println!("cargo:rustc-cfg=arithmetic32");
}
}
4 changes: 2 additions & 2 deletions src/lexical/large_powers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

//! Precalculated large powers for limbs.

#[cfg(limb_width_32)]
#[cfg(arithmetic32)]
pub(crate) use super::large_powers32::*;

#[cfg(limb_width_64)]
#[cfg(arithmetic64)]
pub(crate) use super::large_powers64::*;
20 changes: 10 additions & 10 deletions src/lexical/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,29 @@ use core::{cmp, iter, mem};
// sparc64 (`UMUL` only supported double-word arguments).

// 32-BIT LIMB
#[cfg(limb_width_32)]
#[cfg(arithmetic32)]
pub type Limb = u32;

#[cfg(limb_width_32)]
#[cfg(arithmetic32)]
pub const POW5_LIMB: &[Limb] = &POW5_32;

#[cfg(limb_width_32)]
#[cfg(arithmetic32)]
pub const POW10_LIMB: &[Limb] = &POW10_32;

#[cfg(limb_width_32)]
#[cfg(arithmetic32)]
type Wide = u64;

// 64-BIT LIMB
#[cfg(limb_width_64)]
#[cfg(arithmetic64)]
pub type Limb = u64;

#[cfg(limb_width_64)]
#[cfg(arithmetic64)]
pub const POW5_LIMB: &[Limb] = &POW5_64;

#[cfg(limb_width_64)]
#[cfg(arithmetic64)]
pub const POW10_LIMB: &[Limb] = &POW10_64;

#[cfg(limb_width_64)]
#[cfg(arithmetic64)]
type Wide = u128;

/// Cast to limb type.
Expand All @@ -79,14 +79,14 @@ fn as_wide<T: Integer>(t: T) -> Wide {

/// Split u64 into limbs, in little-endian order.
#[inline]
#[cfg(limb_width_32)]
#[cfg(arithmetic32)]
fn split_u64(x: u64) -> [Limb; 2] {
[as_limb(x), as_limb(x >> 32)]
}

/// Split u64 into limbs, in little-endian order.
#[inline]
#[cfg(limb_width_64)]
#[cfg(arithmetic64)]
fn split_u64(x: u64) -> [Limb; 1] {
[as_limb(x)]
}
Expand Down
4 changes: 2 additions & 2 deletions src/lexical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ pub(crate) mod rounding;
mod shift;
mod small_powers;

#[cfg(limb_width_32)]
#[cfg(arithmetic32)]
mod large_powers32;

#[cfg(limb_width_64)]
#[cfg(arithmetic64)]
mod large_powers64;

// API
Expand Down
6 changes: 3 additions & 3 deletions src/lexical/small_powers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
//! Pre-computed small powers.

// 32 BIT
#[cfg(limb_width_32)]
#[cfg(arithmetic32)]
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)]
#[cfg(arithmetic32)]
pub(crate) const POW10_32: [u32; 10] = [
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
];

// 64 BIT
#[cfg(limb_width_64)]
#[cfg(arithmetic64)]
pub(crate) const POW5_64: [u64; 28] = [
1,
5,
Expand Down
16 changes: 3 additions & 13 deletions src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,20 +446,10 @@ impl<'a> SliceRead<'a> {
// benchmarks and it's cross-platform, so probably the right fit.
// [1]: https://groups.google.com/forum/#!original/comp.lang.c/2HtQXvg7iKc/xOJeipH6KLMJ

// The following architectures have native support for 64-bit integers,
// but have targets where usize is not 64-bit.
#[cfg(any(
target_arch = "aarch64",
target_arch = "x86_64",
target_arch = "wasm32",
))]
#[cfg(arithmetic64)]
type Chunk = u64;
#[cfg(not(any(
target_arch = "aarch64",
target_arch = "x86_64",
target_arch = "wasm32",
)))]
type Chunk = usize;
#[cfg(arithmetic32)]
type Chunk = u32;

const STEP: usize = mem::size_of::<Chunk>();
const ONE_BYTES: Chunk = Chunk::MAX / 255; // 0x0101...01
Expand Down
4 changes: 2 additions & 2 deletions tests/lexical/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ impl Math for Bigint {
}
}

#[cfg(limb_width_32)]
#[cfg(arithmetic32)]
pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
x.iter().cloned().collect()
}

#[cfg(limb_width_64)]
#[cfg(arithmetic64)]
pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
let mut v = Vec::<Limb>::default();
for xi in x.chunks(2) {
Expand Down

0 comments on commit 4b1048d

Please sign in to comment.