core/stdarch/crates/core_arch/src/x86_64/
adx.rs1#[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#[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#[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#[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}