Skip to content

Commit 0322e20

Browse files
gnzlbgalexcrichton
authored andcommitted
Add tests for addcarry and subborrow intrinsics (#672)
1 parent c555782 commit 0322e20

File tree

2 files changed

+209
-2
lines changed

2 files changed

+209
-2
lines changed

crates/core_arch/src/x86/adx.rs

+105-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use stdsimd_test::assert_instr;
55
extern "unadjusted" {
66
#[link_name = "llvm.x86.addcarry.32"]
77
fn llvm_addcarry_u32(a: u8, b: u32, c: u32) -> (u8, u32);
8+
#[link_name = "llvm.x86.addcarryx.u32"]
9+
fn llvm_addcarryx_u32(a: u8, b: u32, c: u32, d: *mut u8) -> u8;
810
#[link_name = "llvm.x86.subborrow.32"]
911
fn llvm_subborrow_u32(a: u8, b: u32, c: u32) -> (u8, u32);
1012
}
@@ -30,7 +32,8 @@ pub unsafe fn _addcarry_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
3032
#[stable(feature = "simd_x86_adx", since = "1.33.0")]
3133
#[cfg(not(stage0))]
3234
pub unsafe fn _addcarryx_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
33-
_addcarry_u32(c_in, a, b, out)
35+
let r = llvm_addcarryx_u32(c_in, a, b, out as *mut _ as *mut u8);
36+
r
3437
}
3538

3639
/// Add unsigned 32-bit integers a and b with unsigned 8-bit carry-in `c_in`
@@ -44,3 +47,104 @@ pub unsafe fn _subborrow_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
4447
*out = b;
4548
a
4649
}
50+
51+
#[cfg(test)]
52+
mod tests {
53+
use stdsimd_test::simd_test;
54+
55+
use core_arch::x86::*;
56+
57+
#[test]
58+
fn test_addcarry_u32() {
59+
unsafe {
60+
let a = u32::max_value();
61+
let mut out = 0;
62+
63+
let r = _addcarry_u32(0, a, 1, &mut out);
64+
assert_eq!(r, 1);
65+
assert_eq!(out, 0);
66+
67+
let r = _addcarry_u32(0, a, 0, &mut out);
68+
assert_eq!(r, 0);
69+
assert_eq!(out, a);
70+
71+
let r = _addcarry_u32(1, a, 1, &mut out);
72+
assert_eq!(r, 1);
73+
assert_eq!(out, 1);
74+
75+
let r = _addcarry_u32(1, a, 0, &mut out);
76+
assert_eq!(r, 1);
77+
assert_eq!(out, 0);
78+
79+
let r = _addcarry_u32(0, 3, 4, &mut out);
80+
assert_eq!(r, 0);
81+
assert_eq!(out, 7);
82+
83+
let r = _addcarry_u32(1, 3, 4, &mut out);
84+
assert_eq!(r, 0);
85+
assert_eq!(out, 8);
86+
}
87+
}
88+
89+
#[simd_test(enable = "adx")]
90+
unsafe fn test_addcarryx_u32() {
91+
let a = u32::max_value();
92+
let mut out = 0;
93+
94+
let r = _addcarry_u32(0, a, 1, &mut out);
95+
assert_eq!(r, 1);
96+
assert_eq!(out, 0);
97+
98+
let r = _addcarry_u32(0, a, 0, &mut out);
99+
assert_eq!(r, 0);
100+
assert_eq!(out, a);
101+
102+
let r = _addcarry_u32(1, a, 1, &mut out);
103+
assert_eq!(r, 1);
104+
assert_eq!(out, 1);
105+
106+
let r = _addcarry_u32(1, a, 0, &mut out);
107+
assert_eq!(r, 1);
108+
assert_eq!(out, 0);
109+
110+
let r = _addcarry_u32(0, 3, 4, &mut out);
111+
assert_eq!(r, 0);
112+
assert_eq!(out, 7);
113+
114+
let r = _addcarry_u32(1, 3, 4, &mut out);
115+
assert_eq!(r, 0);
116+
assert_eq!(out, 8);
117+
}
118+
119+
#[test]
120+
fn test_subborrow_u32() {
121+
unsafe {
122+
let a = u32::max_value();
123+
let mut out = 0;
124+
125+
let r = _subborrow_u32(0, 0, 1, &mut out);
126+
assert_eq!(r, 1);
127+
assert_eq!(out, a);
128+
129+
let r = _subborrow_u32(0, 0, 0, &mut out);
130+
assert_eq!(r, 0);
131+
assert_eq!(out, 0);
132+
133+
let r = _subborrow_u32(1, 0, 1, &mut out);
134+
assert_eq!(r, 1);
135+
assert_eq!(out, a - 1);
136+
137+
let r = _subborrow_u32(1, 0, 0, &mut out);
138+
assert_eq!(r, 1);
139+
assert_eq!(out, a);
140+
141+
let r = _subborrow_u32(0, 7, 3, &mut out);
142+
assert_eq!(r, 0);
143+
assert_eq!(out, 4);
144+
145+
let r = _subborrow_u32(1, 7, 3, &mut out);
146+
assert_eq!(r, 0);
147+
assert_eq!(out, 3);
148+
}
149+
}
150+
}

crates/core_arch/src/x86_64/adx.rs

+104-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use stdsimd_test::assert_instr;
55
extern "unadjusted" {
66
#[link_name = "llvm.x86.addcarry.64"]
77
fn llvm_addcarry_u64(a: u8, b: u64, c: u64) -> (u8, u64);
8+
#[link_name = "llvm.x86.addcarryx.u64"]
9+
fn llvm_addcarryx_u64(a: u8, b: u64, c: u64, d: *mut u8) -> u8;
810
#[link_name = "llvm.x86.subborrow.64"]
911
fn llvm_subborrow_u64(a: u8, b: u64, c: u64) -> (u8, u64);
1012
}
@@ -30,7 +32,7 @@ pub unsafe fn _addcarry_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
3032
#[stable(feature = "simd_x86_adx", since = "1.33.0")]
3133
#[cfg(not(stage0))]
3234
pub unsafe fn _addcarryx_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
33-
_addcarry_u64(c_in, a, b, out)
35+
llvm_addcarryx_u64(c_in, a, b, out as *mut _ as *mut u8)
3436
}
3537

3638
/// Add unsigned 64-bit integers a and b with unsigned 8-bit carry-in `c_in`
@@ -44,3 +46,104 @@ pub unsafe fn _subborrow_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
4446
*out = b;
4547
a
4648
}
49+
50+
#[cfg(test)]
51+
mod tests {
52+
use stdsimd_test::simd_test;
53+
54+
use core_arch::x86_64::*;
55+
56+
#[test]
57+
fn test_addcarry_u64() {
58+
unsafe {
59+
let a = u64::max_value();
60+
let mut out = 0;
61+
62+
let r = _addcarry_u64(0, a, 1, &mut out);
63+
assert_eq!(r, 1);
64+
assert_eq!(out, 0);
65+
66+
let r = _addcarry_u64(0, a, 0, &mut out);
67+
assert_eq!(r, 0);
68+
assert_eq!(out, a);
69+
70+
let r = _addcarry_u64(1, a, 1, &mut out);
71+
assert_eq!(r, 1);
72+
assert_eq!(out, 1);
73+
74+
let r = _addcarry_u64(1, a, 0, &mut out);
75+
assert_eq!(r, 1);
76+
assert_eq!(out, 0);
77+
78+
let r = _addcarry_u64(0, 3, 4, &mut out);
79+
assert_eq!(r, 0);
80+
assert_eq!(out, 7);
81+
82+
let r = _addcarry_u64(1, 3, 4, &mut out);
83+
assert_eq!(r, 0);
84+
assert_eq!(out, 8);
85+
}
86+
}
87+
88+
#[simd_test(enable = "adx")]
89+
unsafe fn test_addcarryx_u64() {
90+
let a = u64::max_value();
91+
let mut out = 0;
92+
93+
let r = _addcarry_u64(0, a, 1, &mut out);
94+
assert_eq!(r, 1);
95+
assert_eq!(out, 0);
96+
97+
let r = _addcarry_u64(0, a, 0, &mut out);
98+
assert_eq!(r, 0);
99+
assert_eq!(out, a);
100+
101+
let r = _addcarry_u64(1, a, 1, &mut out);
102+
assert_eq!(r, 1);
103+
assert_eq!(out, 1);
104+
105+
let r = _addcarry_u64(1, a, 0, &mut out);
106+
assert_eq!(r, 1);
107+
assert_eq!(out, 0);
108+
109+
let r = _addcarry_u64(0, 3, 4, &mut out);
110+
assert_eq!(r, 0);
111+
assert_eq!(out, 7);
112+
113+
let r = _addcarry_u64(1, 3, 4, &mut out);
114+
assert_eq!(r, 0);
115+
assert_eq!(out, 8);
116+
}
117+
118+
#[test]
119+
fn test_subborrow_u64() {
120+
unsafe {
121+
let a = u64::max_value();
122+
let mut out = 0;
123+
124+
let r = _subborrow_u64(0, 0, 1, &mut out);
125+
assert_eq!(r, 1);
126+
assert_eq!(out, a);
127+
128+
let r = _subborrow_u64(0, 0, 0, &mut out);
129+
assert_eq!(r, 0);
130+
assert_eq!(out, 0);
131+
132+
let r = _subborrow_u64(1, 0, 1, &mut out);
133+
assert_eq!(r, 1);
134+
assert_eq!(out, a - 1);
135+
136+
let r = _subborrow_u64(1, 0, 0, &mut out);
137+
assert_eq!(r, 1);
138+
assert_eq!(out, a);
139+
140+
let r = _subborrow_u64(0, 7, 3, &mut out);
141+
assert_eq!(r, 0);
142+
assert_eq!(out, 4);
143+
144+
let r = _subborrow_u64(1, 7, 3, &mut out);
145+
assert_eq!(r, 0);
146+
assert_eq!(out, 3);
147+
}
148+
}
149+
}

0 commit comments

Comments
 (0)