Skip to content

Commit 98efc2b

Browse files
authored
Merge pull request #312 from cuviper/x32
Fixes for target x32
2 parents 124eac8 + 5d530aa commit 98efc2b

File tree

4 files changed

+77
-28
lines changed

4 files changed

+77
-28
lines changed

.github/workflows/ci.yaml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,22 @@ jobs:
4242
- run: cargo build
4343
- run: ./ci/test_full.sh
4444

45+
# try building the x32 target -- x86_64 with target_pointer_width="32"
46+
# (we can't execute without kernel CONFIG_X86_X32_ABI though)
47+
x32:
48+
name: Test (x32)
49+
runs-on: ubuntu-latest
50+
steps:
51+
- run: |
52+
sudo apt-get update
53+
sudo apt-get install gcc-multilib
54+
- uses: actions/checkout@v4
55+
- uses: dtolnay/rust-toolchain@stable
56+
with:
57+
target: x86_64-unknown-linux-gnux32
58+
- run: cargo build --target x86_64-unknown-linux-gnux32 --all-features
59+
- run: cargo test --no-run --target x86_64-unknown-linux-gnux32 --all-features
60+
4561
# try a target that doesn't have std at all, but does have alloc
4662
no_std:
4763
name: No Std
@@ -78,7 +94,7 @@ jobs:
7894
success:
7995
name: Success
8096
runs-on: ubuntu-latest
81-
needs: [test, i686, no_std, fmt, doc]
97+
needs: [test, i686, x32, no_std, fmt, doc]
8298
# Github branch protection is exceedingly silly and treats "jobs skipped because a dependency
8399
# failed" as success. So we have to do some contortions to ensure the job fails if any of its
84100
# dependencies fails.

src/biguint/addition.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,32 @@ use core::iter::Sum;
77
use core::ops::{Add, AddAssign};
88
use num_traits::CheckedAdd;
99

10-
// Add with carry:
1110
#[cfg(target_arch = "x86_64")]
12-
#[inline]
13-
fn adc(carry: u8, a: u64, b: u64, out: &mut u64) -> u8 {
14-
// Safety: There are absolutely no safety concerns with calling `_addcarry_u64`.
15-
// It's just unsafe for API consistency with other intrinsics.
16-
unsafe { core::arch::x86_64::_addcarry_u64(carry, a, b, out) }
17-
}
11+
use core::arch::x86_64 as arch;
1812

1913
#[cfg(target_arch = "x86")]
20-
#[inline]
21-
fn adc(carry: u8, a: u32, b: u32, out: &mut u32) -> u8 {
22-
// Safety: There are absolutely no safety concerns with calling `_addcarry_u32`.
23-
// It's just unsafe for API consistency with other intrinsics.
24-
unsafe { core::arch::x86::_addcarry_u32(carry, a, b, out) }
25-
}
14+
use core::arch::x86 as arch;
15+
16+
// Add with carry:
17+
#[cfg(target_arch = "x86_64")]
18+
cfg_64!(
19+
#[inline]
20+
fn adc(carry: u8, a: u64, b: u64, out: &mut u64) -> u8 {
21+
// Safety: There are absolutely no safety concerns with calling `_addcarry_u64`.
22+
// It's just unsafe for API consistency with other intrinsics.
23+
unsafe { arch::_addcarry_u64(carry, a, b, out) }
24+
}
25+
);
26+
27+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
28+
cfg_32!(
29+
#[inline]
30+
fn adc(carry: u8, a: u32, b: u32, out: &mut u32) -> u8 {
31+
// Safety: There are absolutely no safety concerns with calling `_addcarry_u32`.
32+
// It's just unsafe for API consistency with other intrinsics.
33+
unsafe { arch::_addcarry_u32(carry, a, b, out) }
34+
}
35+
);
2636

2737
// fallback for environments where we don't have an addcarry intrinsic
2838
// (copied from the standard library's `carrying_add`)

src/biguint/division.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,21 @@ fn div_wide(hi: BigDigit, lo: BigDigit, divisor: BigDigit) -> (BigDigit, BigDigi
4444
unsafe {
4545
let (div, rem);
4646

47+
cfg_digit!(
48+
macro_rules! div {
49+
() => {
50+
"div {0:e}"
51+
};
52+
}
53+
macro_rules! div {
54+
() => {
55+
"div {0:r}"
56+
};
57+
}
58+
);
59+
4760
core::arch::asm!(
48-
"div {}",
61+
div!(),
4962
in(reg) divisor,
5063
inout("dx") hi => rem,
5164
inout("ax") lo => div,

src/biguint/subtraction.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,32 @@ use core::cmp::Ordering::{Equal, Greater, Less};
77
use core::ops::{Sub, SubAssign};
88
use num_traits::CheckedSub;
99

10-
// Subtract with borrow:
1110
#[cfg(target_arch = "x86_64")]
12-
#[inline]
13-
fn sbb(borrow: u8, a: u64, b: u64, out: &mut u64) -> u8 {
14-
// Safety: There are absolutely no safety concerns with calling `_subborrow_u64`.
15-
// It's just unsafe for API consistency with other intrinsics.
16-
unsafe { core::arch::x86_64::_subborrow_u64(borrow, a, b, out) }
17-
}
11+
use core::arch::x86_64 as arch;
1812

1913
#[cfg(target_arch = "x86")]
20-
#[inline]
21-
fn sbb(borrow: u8, a: u32, b: u32, out: &mut u32) -> u8 {
22-
// Safety: There are absolutely no safety concerns with calling `_subborrow_u32`.
23-
// It's just unsafe for API consistency with other intrinsics.
24-
unsafe { core::arch::x86::_subborrow_u32(borrow, a, b, out) }
25-
}
14+
use core::arch::x86 as arch;
15+
16+
// Subtract with borrow:
17+
#[cfg(target_arch = "x86_64")]
18+
cfg_64!(
19+
#[inline]
20+
fn sbb(borrow: u8, a: u64, b: u64, out: &mut u64) -> u8 {
21+
// Safety: There are absolutely no safety concerns with calling `_subborrow_u64`.
22+
// It's just unsafe for API consistency with other intrinsics.
23+
unsafe { arch::_subborrow_u64(borrow, a, b, out) }
24+
}
25+
);
26+
27+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
28+
cfg_32!(
29+
#[inline]
30+
fn sbb(borrow: u8, a: u32, b: u32, out: &mut u32) -> u8 {
31+
// Safety: There are absolutely no safety concerns with calling `_subborrow_u32`.
32+
// It's just unsafe for API consistency with other intrinsics.
33+
unsafe { arch::_subborrow_u32(borrow, a, b, out) }
34+
}
35+
);
2636

2737
// fallback for environments where we don't have a subborrow intrinsic
2838
// (copied from the standard library's `borrowing_sub`)

0 commit comments

Comments
 (0)