From 3fda53a90d048fe9b2220817e502f2ccb02b5d98 Mon Sep 17 00:00:00 2001 From: Aaron Kutch Date: Sun, 3 May 2020 22:40:54 -0500 Subject: [PATCH] replace old soft division code with new functions --- library/compiler-builtins/src/int/sdiv.rs | 23 +++--- library/compiler-builtins/src/int/udiv.rs | 86 +++++------------------ 2 files changed, 33 insertions(+), 76 deletions(-) diff --git a/library/compiler-builtins/src/int/sdiv.rs b/library/compiler-builtins/src/int/sdiv.rs index 854ea00bbd81..983c34cf36d3 100644 --- a/library/compiler-builtins/src/int/sdiv.rs +++ b/library/compiler-builtins/src/int/sdiv.rs @@ -57,54 +57,59 @@ trait Divmod: Int { impl Divmod for i32 {} impl Divmod for i64 {} + intrinsics! { #[maybe_use_optimized_c_shim] #[arm_aeabi_alias = __aeabi_idiv] /// Returns `n / d` pub extern "C" fn __divsi3(a: i32, b: i32) -> i32 { - a.div(b) + i32_div_rem(a, b).0 } #[maybe_use_optimized_c_shim] /// Returns `n % d` pub extern "C" fn __modsi3(a: i32, b: i32) -> i32 { - a.mod_(b) + i32_div_rem(a, b).1 } - + #[maybe_use_optimized_c_shim] /// Returns `n / d` and sets `*rem = n % d` pub extern "C" fn __divmodsi4(a: i32, b: i32, rem: &mut i32) -> i32 { - a.divmod(b, rem, |a, b| __divsi3(a, b)) + let quo_rem = i32_div_rem(a, b); + *rem = quo_rem.1; + quo_rem.0 } #[maybe_use_optimized_c_shim] /// Returns `n / d` pub extern "C" fn __divdi3(a: i64, b: i64) -> i64 { - a.div(b) + i64_div_rem(a, b).0 } #[maybe_use_optimized_c_shim] /// Returns `n % d` pub extern "C" fn __moddi3(a: i64, b: i64) -> i64 { - a.mod_(b) + i64_div_rem(a, b).1 } #[aapcs_on_arm] /// Returns `n / d` and sets `*rem = n % d` pub extern "C" fn __divmoddi4(a: i64, b: i64, rem: &mut i64) -> i64 { - a.divmod(b, rem, |a, b| __divdi3(a, b)) + let quo_rem = i64_div_rem(a, b); + *rem = quo_rem.1; + quo_rem.0 } #[win64_128bit_abi_hack] /// Returns `n / d` pub extern "C" fn __divti3(a: i128, b: i128) -> i128 { - a.div(b) + i128_div_rem(a, b).0 } #[win64_128bit_abi_hack] /// Returns `n % d` pub extern "C" fn __modti3(a: i128, b: i128) -> i128 { - a.mod_(b) + i128_div_rem(a, b).1 } // LLVM does not currently have a `__divmodti4` function diff --git a/library/compiler-builtins/src/int/udiv.rs b/library/compiler-builtins/src/int/udiv.rs index 1ee670c72abd..b312ca48b049 100644 --- a/library/compiler-builtins/src/int/udiv.rs +++ b/library/compiler-builtins/src/int/udiv.rs @@ -156,113 +156,65 @@ intrinsics! { #[arm_aeabi_alias = __aeabi_uidiv] /// Returns `n / d` pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 { - // Special cases - if d == 0 { - // NOTE This should be unreachable in safe Rust because the program will panic before - // this intrinsic is called - ::abort(); - } - - if n == 0 { - return 0; - } - - let mut sr = d.leading_zeros().wrapping_sub(n.leading_zeros()); - - // d > n - if sr > u32::BITS - 1 { - return 0; - } - - // d == 1 - if sr == u32::BITS - 1 { - return n; - } - - sr += 1; - - // 1 <= sr <= u32::BITS - 1 - let mut q = n << (u32::BITS - sr); - let mut r = n >> sr; - - let mut carry = 0; - - // Don't use a range because they may generate references to memcpy in unoptimized code - let mut i = 0; - while i < sr { - i += 1; - - // r:q = ((r:q) << 1) | carry - r = (r << 1) | (q >> (u32::BITS - 1)); - q = (q << 1) | carry; - - // carry = 0; - // if r > d { - // r -= d; - // carry = 1; - // } - - let s = (d.wrapping_sub(r).wrapping_sub(1)) as i32 >> (u32::BITS - 1); - carry = (s & 1) as u32; - r -= d & s as u32; - } - - (q << 1) | carry + u32_div_rem(n, d).0 } #[maybe_use_optimized_c_shim] /// Returns `n % d` pub extern "C" fn __umodsi3(n: u32, d: u32) -> u32 { - let q = __udivsi3(n, d); - n - q * d + u32_div_rem(n, d).1 } #[maybe_use_optimized_c_shim] /// Returns `n / d` and sets `*rem = n % d` pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 { - let q = __udivsi3(n, d); + let quo_rem = u32_div_rem(n, d); if let Some(rem) = rem { - *rem = n - (q * d); + *rem = quo_rem.1; } - q + quo_rem.0 } #[maybe_use_optimized_c_shim] /// Returns `n / d` pub extern "C" fn __udivdi3(n: u64, d: u64) -> u64 { - __udivmoddi4(n, d, None) + u64_div_rem(n, d).0 } #[maybe_use_optimized_c_shim] /// Returns `n % d` pub extern "C" fn __umoddi3(n: u64, d: u64) -> u64 { - let mut rem = 0; - __udivmoddi4(n, d, Some(&mut rem)); - rem + u64_div_rem(n, d).1 } /// Returns `n / d` and sets `*rem = n % d` pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 { - udivmod_inner!(n, d, rem, u64) + let quo_rem = u64_div_rem(n, d); + if let Some(rem) = rem { + *rem = quo_rem.1; + } + quo_rem.0 } #[win64_128bit_abi_hack] /// Returns `n / d` pub extern "C" fn __udivti3(n: u128, d: u128) -> u128 { - __udivmodti4(n, d, None) + u128_div_rem(n, d).0 } #[win64_128bit_abi_hack] /// Returns `n % d` pub extern "C" fn __umodti3(n: u128, d: u128) -> u128 { - let mut rem = 0; - __udivmodti4(n, d, Some(&mut rem)); - rem + u128_div_rem(n, d).1 } #[win64_128bit_abi_hack] /// Returns `n / d` and sets `*rem = n % d` pub extern "C" fn __udivmodti4(n: u128, d: u128, rem: Option<&mut u128>) -> u128 { - udivmod_inner!(n, d, rem, u128) + let quo_rem = u128_div_rem(n, d); + if let Some(rem) = rem { + *rem = quo_rem.1; + } + quo_rem.0 } }