core/stdarch/crates/core_arch/src/x86/
adx.rs1#[cfg(test)]
2use stdarch_test::assert_instr;
3
4#[allow(improper_ctypes)]
5unsafe extern "unadjusted" {
6 #[link_name = "llvm.x86.addcarry.32"]
7 fn llvm_addcarry_u32(a: u8, b: u32, c: u32) -> (u8, u32);
8 #[link_name = "llvm.x86.subborrow.32"]
9 fn llvm_subborrow_u32(a: u8, b: u32, c: u32) -> (u8, u32);
10}
11
12#[inline]
18#[cfg_attr(test, assert_instr(adc))]
19#[stable(feature = "simd_x86_adx", since = "1.33.0")]
20pub fn _addcarry_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
21 let (a, b) = unsafe { llvm_addcarry_u32(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_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
36 _addcarry_u32(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_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
48 let (a, b) = unsafe { llvm_subborrow_u32(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::*;
58
59 #[test]
60 fn test_addcarry_u32() {
61 let a = u32::MAX;
62 let mut out = 0;
63
64 let r = _addcarry_u32(0, a, 1, &mut out);
65 assert_eq!(r, 1);
66 assert_eq!(out, 0);
67
68 let r = _addcarry_u32(0, a, 0, &mut out);
69 assert_eq!(r, 0);
70 assert_eq!(out, a);
71
72 let r = _addcarry_u32(1, a, 1, &mut out);
73 assert_eq!(r, 1);
74 assert_eq!(out, 1);
75
76 let r = _addcarry_u32(1, a, 0, &mut out);
77 assert_eq!(r, 1);
78 assert_eq!(out, 0);
79
80 let r = _addcarry_u32(0, 3, 4, &mut out);
81 assert_eq!(r, 0);
82 assert_eq!(out, 7);
83
84 let r = _addcarry_u32(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_u32() {
91 let a = u32::MAX;
92 let mut out = 0;
93
94 let r = _addcarryx_u32(0, a, 1, &mut out);
95 assert_eq!(r, 1);
96 assert_eq!(out, 0);
97
98 let r = _addcarryx_u32(0, a, 0, &mut out);
99 assert_eq!(r, 0);
100 assert_eq!(out, a);
101
102 let r = _addcarryx_u32(1, a, 1, &mut out);
103 assert_eq!(r, 1);
104 assert_eq!(out, 1);
105
106 let r = _addcarryx_u32(1, a, 0, &mut out);
107 assert_eq!(r, 1);
108 assert_eq!(out, 0);
109
110 let r = _addcarryx_u32(0, 3, 4, &mut out);
111 assert_eq!(r, 0);
112 assert_eq!(out, 7);
113
114 let r = _addcarryx_u32(1, 3, 4, &mut out);
115 assert_eq!(r, 0);
116 assert_eq!(out, 8);
117 }
118
119 #[simd_test(enable = "adx")]
120 fn test_addcarryx_u32_2() {
121 let mut out = 0;
122 _addcarryx_u32(1, 2, 3, &mut out);
123 assert_eq!(6, out);
124 }
125
126 #[test]
127 fn test_subborrow_u32() {
128 let a = u32::MAX;
129 let mut out = 0;
130
131 let r = _subborrow_u32(0, 0, 1, &mut out);
132 assert_eq!(r, 1);
133 assert_eq!(out, a);
134
135 let r = _subborrow_u32(0, 0, 0, &mut out);
136 assert_eq!(r, 0);
137 assert_eq!(out, 0);
138
139 let r = _subborrow_u32(1, 0, 1, &mut out);
140 assert_eq!(r, 1);
141 assert_eq!(out, a - 1);
142
143 let r = _subborrow_u32(1, 0, 0, &mut out);
144 assert_eq!(r, 1);
145 assert_eq!(out, a);
146
147 let r = _subborrow_u32(0, 7, 3, &mut out);
148 assert_eq!(r, 0);
149 assert_eq!(out, 4);
150
151 let r = _subborrow_u32(1, 7, 3, &mut out);
152 assert_eq!(r, 0);
153 assert_eq!(out, 3);
154 }
155}