Skip to content

Commit 49ff7b7

Browse files
ejmahlercuviper
authored andcommitted
Backed out adc and sbb parameter rearrangement, implemented u32 for x64, applied rustfmt
1 parent 0be00d8 commit 49ff7b7

File tree

2 files changed

+59
-24
lines changed

2 files changed

+59
-24
lines changed

build.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,16 @@ fn main() {
1515
autocfg::emit("has_try_from");
1616
}
1717

18-
if u64_digit && (ac.probe_path("core::arch::x86_64::_addcarry_u64") || ac.probe_path("std::arch::x86_64::_addcarry_u64")) {
18+
if u64_digit
19+
&& (ac.probe_path("core::arch::x86_64::_addcarry_u64")
20+
|| ac.probe_path("std::arch::x86_64::_addcarry_u64"))
21+
{
1922
autocfg::emit("use_addcarry_u64");
23+
} else if !u64_digit
24+
&& (ac.probe_path("core::arch::x86_64::_addcarry_u32")
25+
|| ac.probe_path("core::arch::x86::_addcarry_u32"))
26+
{
27+
autocfg::emit("use_addcarry_u32");
2028
}
2129

2230
autocfg::rerun_path("build.rs");

src/algorithms.rs

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,67 @@ use crate::bigint::Sign::{Minus, NoSign, Plus};
1414

1515
use crate::big_digit::{self, BigDigit, DoubleBigDigit};
1616

17-
#[cfg(not(use_addcarry_u64))] // only needed for the fallback implementation of `sbb`
17+
// only needed for the fallback implementation of `sbb`
18+
#[cfg(not(any(use_addcarry_u64, use_addcarry_u32)))]
1819
use crate::big_digit::SignedDoubleBigDigit;
1920

20-
// Generic functions for add/subtract/multiply with carry/borrow:
21+
// Generic functions for add/subtract/multiply with carry/borrow. These are specialized for some platforms to take advantage of intrinsics etc
2122

2223
// Add with carry:
2324
#[cfg(use_addcarry_u64)]
2425
#[inline]
25-
fn adc(carry: u8, a: BigDigit, b: BigDigit, out: &mut BigDigit) -> u8 {
26-
unsafe { core::arch::x86_64::_addcarry_u64(carry, a, b, out) }
26+
fn adc(a: BigDigit, b: BigDigit, acc: &mut u8) -> BigDigit {
27+
let mut out = 0;
28+
// Safety: There are absolutely no safety concerns with calling _addcarry_u64, it's just unsafe for API consistency with other intrinsics
29+
*acc = unsafe { core::arch::x86_64::_addcarry_u64(*acc, a, b, &mut out) };
30+
out
2731
}
2832

29-
#[cfg(not(use_addcarry_u64))] // fallback for environments where we don't have an addcarry intrinsic
33+
#[cfg(use_addcarry_u32)]
3034
#[inline]
31-
fn adc(mut carry: DoubleBigDigit, a: BigDigit, b: BigDigit, out: &mut BigDigit) -> DoubleBigDigit {
32-
carry += DoubleBigDigit::from(a);
33-
carry += DoubleBigDigit::from(b);
34-
*out = carry as BigDigit;
35-
carry >> big_digit::BITS
35+
fn adc(a: BigDigit, b: BigDigit, acc: &mut u8) -> BigDigit {
36+
let mut out = 0;
37+
// Safety: There are absolutely no safety concerns with calling _addcarry_u64, it's just unsafe for API consistency with other intrinsics
38+
*acc = unsafe { core::arch::x86_64::_addcarry_u32(*acc, a, b, &mut out) };
39+
out
40+
}
41+
42+
#[cfg(not(any(use_addcarry_u64, use_addcarry_u32)))] // fallback for environments where we don't have an addcarry intrinsic
43+
#[inline]
44+
fn adc(a: BigDigit, b: BigDigit, acc: &mut DoubleBigDigit) -> BigDigit {
45+
*acc += DoubleBigDigit::from(a);
46+
*acc += DoubleBigDigit::from(b);
47+
let lo = *acc as BigDigit;
48+
*acc >>= big_digit::BITS;
49+
lo
3650
}
3751

3852
// Subtract with borrow:
3953
#[cfg(use_addcarry_u64)]
4054
#[inline]
41-
fn sbb(carry: u8, a: BigDigit, b: BigDigit, out: &mut BigDigit) -> u8 {
42-
unsafe { core::arch::x86_64::_subborrow_u64(carry, a, b, out) }
55+
fn sbb(a: BigDigit, b: BigDigit, acc: &mut u8) -> BigDigit {
56+
let mut out = 0;
57+
// Safety: There are absolutely no safety concerns with calling _addcarry_u64, it's just unsafe for API consistency with other intrinsics
58+
*acc = unsafe { core::arch::x86_64::_subborrow_u64(*acc, a, b, &mut out) };
59+
out
4360
}
44-
#[cfg(not(use_addcarry_u64))] // fallback for environments where we don't have an addcarry intrinsic
61+
#[cfg(use_addcarry_u32)]
4562
#[inline]
46-
fn sbb(mut carry: SignedDoubleBigDigit, a: BigDigit, b: BigDigit, out: &mut BigDigit) -> SignedDoubleBigDigit {
47-
carry += SignedDoubleBigDigit::from(a);
48-
carry -= SignedDoubleBigDigit::from(b);
49-
*out = carry as BigDigit;
50-
carry >> big_digit::BITS
63+
fn sbb(a: BigDigit, b: BigDigit, acc: &mut u8) -> BigDigit {
64+
let mut out = 0;
65+
// Safety: There are absolutely no safety concerns with calling _addcarry_u64, it's just unsafe for API consistency with other intrinsics
66+
*acc = unsafe { core::arch::x86_64::_subborrow_u32(*acc, a, b, &mut out) };
67+
out
68+
}
69+
70+
#[cfg(not(any(use_addcarry_u64, use_addcarry_u32)))] // fallback for environments where we don't have an addcarry intrinsic
71+
#[inline]
72+
fn sbb(a: BigDigit, b: BigDigit, acc: &mut SignedDoubleBigDigit) -> BigDigit {
73+
*acc += SignedDoubleBigDigit::from(a);
74+
*acc -= SignedDoubleBigDigit::from(b);
75+
let lo = *acc as BigDigit;
76+
*acc >>= big_digit::BITS;
77+
lo
5178
}
5279

5380
#[inline]
@@ -154,12 +181,12 @@ pub(crate) fn __add2(a: &mut [BigDigit], b: &[BigDigit]) -> BigDigit {
154181
let (a_lo, a_hi) = a.split_at_mut(b.len());
155182

156183
for (a, b) in a_lo.iter_mut().zip(b) {
157-
carry = adc(carry, *a, *b, a);
184+
*a = adc(*a, *b, &mut carry);
158185
}
159186

160187
if carry != 0 {
161188
for a in a_hi {
162-
carry = adc(carry, *a, 0, a);
189+
*a = adc(*a, 0, &mut carry);
163190
if carry == 0 {
164191
break;
165192
}
@@ -188,12 +215,12 @@ pub(crate) fn sub2(a: &mut [BigDigit], b: &[BigDigit]) {
188215
let (b_lo, b_hi) = b.split_at(len);
189216

190217
for (a, b) in a_lo.iter_mut().zip(b_lo) {
191-
borrow = sbb(borrow, *a, *b, a);
218+
*a = sbb(*a, *b, &mut borrow);
192219
}
193220

194221
if borrow != 0 {
195222
for a in a_hi {
196-
borrow = sbb(borrow, *a, 0, a);
223+
*a = sbb(*a, 0, &mut borrow);
197224
if borrow == 0 {
198225
break;
199226
}
@@ -215,7 +242,7 @@ pub(crate) fn __sub2rev(a: &[BigDigit], b: &mut [BigDigit]) -> BigDigit {
215242
let mut borrow = 0;
216243

217244
for (ai, bi) in a.iter().zip(b) {
218-
borrow = sbb(borrow, *ai, *bi, bi);
245+
*bi = sbb(*ai, *bi, &mut borrow);
219246
}
220247

221248
borrow as BigDigit

0 commit comments

Comments
 (0)