Skip to content
This repository has been archived by the owner on Jun 7, 2020. It is now read-only.

Commit

Permalink
Add tests for addcarry and subborrow intrinsics (rust-lang#672)
Browse files Browse the repository at this point in the history
  • Loading branch information
gnzlbg authored and alexcrichton committed Jan 31, 2019
1 parent c555782 commit 0322e20
Show file tree
Hide file tree
Showing 2 changed files with 209 additions and 2 deletions.
106 changes: 105 additions & 1 deletion crates/core_arch/src/x86/adx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use stdsimd_test::assert_instr;
extern "unadjusted" {
#[link_name = "llvm.x86.addcarry.32"]
fn llvm_addcarry_u32(a: u8, b: u32, c: u32) -> (u8, u32);
#[link_name = "llvm.x86.addcarryx.u32"]
fn llvm_addcarryx_u32(a: u8, b: u32, c: u32, d: *mut u8) -> u8;
#[link_name = "llvm.x86.subborrow.32"]
fn llvm_subborrow_u32(a: u8, b: u32, c: u32) -> (u8, u32);
}
Expand All @@ -30,7 +32,8 @@ pub unsafe fn _addcarry_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
#[stable(feature = "simd_x86_adx", since = "1.33.0")]
#[cfg(not(stage0))]
pub unsafe fn _addcarryx_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
_addcarry_u32(c_in, a, b, out)
let r = llvm_addcarryx_u32(c_in, a, b, out as *mut _ as *mut u8);
r
}

/// Add unsigned 32-bit integers a and b with unsigned 8-bit carry-in `c_in`
Expand All @@ -44,3 +47,104 @@ pub unsafe fn _subborrow_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
*out = b;
a
}

#[cfg(test)]
mod tests {
use stdsimd_test::simd_test;

use core_arch::x86::*;

#[test]
fn test_addcarry_u32() {
unsafe {
let a = u32::max_value();
let mut out = 0;

let r = _addcarry_u32(0, a, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 0);

let r = _addcarry_u32(0, a, 0, &mut out);
assert_eq!(r, 0);
assert_eq!(out, a);

let r = _addcarry_u32(1, a, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 1);

let r = _addcarry_u32(1, a, 0, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 0);

let r = _addcarry_u32(0, 3, 4, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 7);

let r = _addcarry_u32(1, 3, 4, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 8);
}
}

#[simd_test(enable = "adx")]
unsafe fn test_addcarryx_u32() {
let a = u32::max_value();
let mut out = 0;

let r = _addcarry_u32(0, a, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 0);

let r = _addcarry_u32(0, a, 0, &mut out);
assert_eq!(r, 0);
assert_eq!(out, a);

let r = _addcarry_u32(1, a, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 1);

let r = _addcarry_u32(1, a, 0, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 0);

let r = _addcarry_u32(0, 3, 4, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 7);

let r = _addcarry_u32(1, 3, 4, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 8);
}

#[test]
fn test_subborrow_u32() {
unsafe {
let a = u32::max_value();
let mut out = 0;

let r = _subborrow_u32(0, 0, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, a);

let r = _subborrow_u32(0, 0, 0, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 0);

let r = _subborrow_u32(1, 0, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, a - 1);

let r = _subborrow_u32(1, 0, 0, &mut out);
assert_eq!(r, 1);
assert_eq!(out, a);

let r = _subborrow_u32(0, 7, 3, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 4);

let r = _subborrow_u32(1, 7, 3, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 3);
}
}
}
105 changes: 104 additions & 1 deletion crates/core_arch/src/x86_64/adx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use stdsimd_test::assert_instr;
extern "unadjusted" {
#[link_name = "llvm.x86.addcarry.64"]
fn llvm_addcarry_u64(a: u8, b: u64, c: u64) -> (u8, u64);
#[link_name = "llvm.x86.addcarryx.u64"]
fn llvm_addcarryx_u64(a: u8, b: u64, c: u64, d: *mut u8) -> u8;
#[link_name = "llvm.x86.subborrow.64"]
fn llvm_subborrow_u64(a: u8, b: u64, c: u64) -> (u8, u64);
}
Expand All @@ -30,7 +32,7 @@ pub unsafe fn _addcarry_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
#[stable(feature = "simd_x86_adx", since = "1.33.0")]
#[cfg(not(stage0))]
pub unsafe fn _addcarryx_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
_addcarry_u64(c_in, a, b, out)
llvm_addcarryx_u64(c_in, a, b, out as *mut _ as *mut u8)
}

/// Add unsigned 64-bit integers a and b with unsigned 8-bit carry-in `c_in`
Expand All @@ -44,3 +46,104 @@ pub unsafe fn _subborrow_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
*out = b;
a
}

#[cfg(test)]
mod tests {
use stdsimd_test::simd_test;

use core_arch::x86_64::*;

#[test]
fn test_addcarry_u64() {
unsafe {
let a = u64::max_value();
let mut out = 0;

let r = _addcarry_u64(0, a, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 0);

let r = _addcarry_u64(0, a, 0, &mut out);
assert_eq!(r, 0);
assert_eq!(out, a);

let r = _addcarry_u64(1, a, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 1);

let r = _addcarry_u64(1, a, 0, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 0);

let r = _addcarry_u64(0, 3, 4, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 7);

let r = _addcarry_u64(1, 3, 4, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 8);
}
}

#[simd_test(enable = "adx")]
unsafe fn test_addcarryx_u64() {
let a = u64::max_value();
let mut out = 0;

let r = _addcarry_u64(0, a, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 0);

let r = _addcarry_u64(0, a, 0, &mut out);
assert_eq!(r, 0);
assert_eq!(out, a);

let r = _addcarry_u64(1, a, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 1);

let r = _addcarry_u64(1, a, 0, &mut out);
assert_eq!(r, 1);
assert_eq!(out, 0);

let r = _addcarry_u64(0, 3, 4, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 7);

let r = _addcarry_u64(1, 3, 4, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 8);
}

#[test]
fn test_subborrow_u64() {
unsafe {
let a = u64::max_value();
let mut out = 0;

let r = _subborrow_u64(0, 0, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, a);

let r = _subborrow_u64(0, 0, 0, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 0);

let r = _subborrow_u64(1, 0, 1, &mut out);
assert_eq!(r, 1);
assert_eq!(out, a - 1);

let r = _subborrow_u64(1, 0, 0, &mut out);
assert_eq!(r, 1);
assert_eq!(out, a);

let r = _subborrow_u64(0, 7, 3, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 4);

let r = _subborrow_u64(1, 7, 3, &mut out);
assert_eq!(r, 0);
assert_eq!(out, 3);
}
}
}

0 comments on commit 0322e20

Please sign in to comment.