adx.rs - source
Description: Source of the Rust file `library/core/src/../../stdarch/crates/core_arch/src/x86_64/adx.rs`.

#
core/stdarch/crates/core_arch/src/x86_64/
adx.rs

    1#[cfg(test)]
    2use stdarch_test::assert_instr;
    3
    4#[allow(improper_ctypes)]
    5unsafe extern "unadjusted" {
    6    #[link_name = "llvm.x86.addcarry.64"]
    7    fn llvm_addcarry_u64(a: u8, b: u64, c: u64) -> (u8, u64);
    8    #[link_name = "llvm.x86.subborrow.64"]
    9    fn llvm_subborrow_u64(a: u8, b: u64, c: u64) -> (u8, u64);
    10}
    11
    12/// Adds unsigned 64-bit integers `a` and `b` with unsigned 8-bit carry-in `c_in`
    13/// (carry or overflow flag), and store the unsigned 64-bit result in `out`, and the carry-out
    14/// is returned (carry or overflow flag).
    15///
    16/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_addcarry_u64)
    17#[inline]
    18#[cfg_attr(test, assert_instr(adc))]
    19#[stable(feature = "simd_x86_adx", since = "1.33.0")]
    20pub fn _addcarry_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
    21    let (a, b) = unsafe { llvm_addcarry_u64(c_in, a, b) };
    22    *out = b;
    23    a
    24}
    25
    26/// Adds unsigned 64-bit integers `a` and `b` with unsigned 8-bit carry-in `c_in`
    27/// (carry or overflow flag), and store the unsigned 64-bit result in `out`, and
    28/// the carry-out is returned (carry or overflow flag).
    29///
    30/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_addcarryx_u64)
    31#[inline]
    32#[target_feature(enable = "adx")]
    33#[cfg_attr(test, assert_instr(adc))]
    34#[stable(feature = "simd_x86_adx", since = "1.33.0")]
    35pub fn _addcarryx_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
    36    _addcarry_u64(c_in, a, b, out)
    37}
    38
    39/// Adds unsigned 64-bit integers `a` and `b` with unsigned 8-bit carry-in `c_in`.
    40/// (carry or overflow flag), and store the unsigned 64-bit result in `out`, and
    41/// the carry-out is returned (carry or overflow flag).
    42///
    43/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_subborrow_u64)
    44#[inline]
    45#[cfg_attr(test, assert_instr(sbb))]
    46#[stable(feature = "simd_x86_adx", since = "1.33.0")]
    47pub fn _subborrow_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
    48    let (a, b) = unsafe { llvm_subborrow_u64(c_in, a, b) };
    49    *out = b;
    50    a
    51}
    52
    53#[cfg(test)]
    54mod tests {
    55    use stdarch_test::simd_test;
    56
    57    use crate::core_arch::x86_64::*;
    58
    59    #[test]
    60    fn test_addcarry_u64() {
    61        let a = u64::MAX;
    62        let mut out = 0;
    63
    64        let r = _addcarry_u64(0, a, 1, &mut out);
    65        assert_eq!(r, 1);
    66        assert_eq!(out, 0);
    67
    68        let r = _addcarry_u64(0, a, 0, &mut out);
    69        assert_eq!(r, 0);
    70        assert_eq!(out, a);
    71
    72        let r = _addcarry_u64(1, a, 1, &mut out);
    73        assert_eq!(r, 1);
    74        assert_eq!(out, 1);
    75
    76        let r = _addcarry_u64(1, a, 0, &mut out);
    77        assert_eq!(r, 1);
    78        assert_eq!(out, 0);
    79
    80        let r = _addcarry_u64(0, 3, 4, &mut out);
    81        assert_eq!(r, 0);
    82        assert_eq!(out, 7);
    83
    84        let r = _addcarry_u64(1, 3, 4, &mut out);
    85        assert_eq!(r, 0);
    86        assert_eq!(out, 8);
    87    }
    88
    89    #[simd_test(enable = "adx")]
    90    fn test_addcarryx_u64() {
    91        let a = u64::MAX;
    92        let mut out = 0;
    93
    94        let r = _addcarryx_u64(0, a, 1, &mut out);
    95        assert_eq!(r, 1);
    96        assert_eq!(out, 0);
    97
    98        let r = _addcarryx_u64(0, a, 0, &mut out);
    99        assert_eq!(r, 0);
    100        assert_eq!(out, a);
    101
    102        let r = _addcarryx_u64(1, a, 1, &mut out);
    103        assert_eq!(r, 1);
    104        assert_eq!(out, 1);
    105
    106        let r = _addcarryx_u64(1, a, 0, &mut out);
    107        assert_eq!(r, 1);
    108        assert_eq!(out, 0);
    109
    110        let r = _addcarryx_u64(0, 3, 4, &mut out);
    111        assert_eq!(r, 0);
    112        assert_eq!(out, 7);
    113
    114        let r = _addcarryx_u64(1, 3, 4, &mut out);
    115        assert_eq!(r, 0);
    116        assert_eq!(out, 8);
    117    }
    118
    119    #[test]
    120    fn test_subborrow_u64() {
    121        let a = u64::MAX;
    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}