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.addcarryx.u32"]
9 fn llvm_addcarryx_u32(a: u8, b: u32, c: u32, d: *mut u32) -> u8;
10 #[link_name = "llvm.x86.subborrow.32"]
11 fn llvm_subborrow_u32(a: u8, b: u32, c: u32) -> (u8, u32);
12}
13
14#[inline]
20#[cfg_attr(test, assert_instr(adc))]
21#[stable(feature = "simd_x86_adx", since = "1.33.0")]
22pub unsafe fn _addcarry_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
23 let (a, b) = llvm_addcarry_u32(c_in, a, b);
24 *out = b;
25 a
26}
27
28#[inline]
34#[target_feature(enable = "adx")]
35#[cfg_attr(test, assert_instr(adc))]
36#[stable(feature = "simd_x86_adx", since = "1.33.0")]
37pub unsafe fn _addcarryx_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
38 llvm_addcarryx_u32(c_in, a, b, out as *mut _)
39}
40
41#[inline]
47#[cfg_attr(test, assert_instr(sbb))]
48#[stable(feature = "simd_x86_adx", since = "1.33.0")]
49pub unsafe fn _subborrow_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
50 let (a, b) = llvm_subborrow_u32(c_in, a, b);
51 *out = b;
52 a
53}
54
55#[cfg(test)]
56mod tests {
57 use stdarch_test::simd_test;
58
59 use crate::core_arch::x86::*;
60
61 #[test]
62 fn test_addcarry_u32() {
63 unsafe {
64 let a = u32::MAX;
65 let mut out = 0;
66
67 let r = _addcarry_u32(0, a, 1, &mut out);
68 assert_eq!(r, 1);
69 assert_eq!(out, 0);
70
71 let r = _addcarry_u32(0, a, 0, &mut out);
72 assert_eq!(r, 0);
73 assert_eq!(out, a);
74
75 let r = _addcarry_u32(1, a, 1, &mut out);
76 assert_eq!(r, 1);
77 assert_eq!(out, 1);
78
79 let r = _addcarry_u32(1, a, 0, &mut out);
80 assert_eq!(r, 1);
81 assert_eq!(out, 0);
82
83 let r = _addcarry_u32(0, 3, 4, &mut out);
84 assert_eq!(r, 0);
85 assert_eq!(out, 7);
86
87 let r = _addcarry_u32(1, 3, 4, &mut out);
88 assert_eq!(r, 0);
89 assert_eq!(out, 8);
90 }
91 }
92
93 #[simd_test(enable = "adx")]
94 unsafe fn test_addcarryx_u32() {
95 let a = u32::MAX;
96 let mut out = 0;
97
98 let r = _addcarryx_u32(0, a, 1, &mut out);
99 assert_eq!(r, 1);
100 assert_eq!(out, 0);
101
102 let r = _addcarryx_u32(0, a, 0, &mut out);
103 assert_eq!(r, 0);
104 assert_eq!(out, a);
105
106 let r = _addcarryx_u32(1, a, 1, &mut out);
107 assert_eq!(r, 1);
108 assert_eq!(out, 1);
109
110 let r = _addcarryx_u32(1, a, 0, &mut out);
111 assert_eq!(r, 1);
112 assert_eq!(out, 0);
113
114 let r = _addcarryx_u32(0, 3, 4, &mut out);
115 assert_eq!(r, 0);
116 assert_eq!(out, 7);
117
118 let r = _addcarryx_u32(1, 3, 4, &mut out);
119 assert_eq!(r, 0);
120 assert_eq!(out, 8);
121 }
122
123 #[simd_test(enable = "adx")]
124 unsafe fn test_addcarryx_u32_2() {
125 unsafe fn add_1_2_3() -> u32 {
126 let mut out = 0;
127 _addcarryx_u32(1, 2, 3, &mut out);
128 out
129 }
130 assert_eq!(6, add_1_2_3());
131 }
132
133 #[test]
134 fn test_subborrow_u32() {
135 unsafe {
136 let a = u32::MAX;
137 let mut out = 0;
138
139 let r = _subborrow_u32(0, 0, 1, &mut out);
140 assert_eq!(r, 1);
141 assert_eq!(out, a);
142
143 let r = _subborrow_u32(0, 0, 0, &mut out);
144 assert_eq!(r, 0);
145 assert_eq!(out, 0);
146
147 let r = _subborrow_u32(1, 0, 1, &mut out);
148 assert_eq!(r, 1);
149 assert_eq!(out, a - 1);
150
151 let r = _subborrow_u32(1, 0, 0, &mut out);
152 assert_eq!(r, 1);
153 assert_eq!(out, a);
154
155 let r = _subborrow_u32(0, 7, 3, &mut out);
156 assert_eq!(r, 0);
157 assert_eq!(out, 4);
158
159 let r = _subborrow_u32(1, 7, 3, &mut out);
160 assert_eq!(r, 0);
161 assert_eq!(out, 3);
162 }
163 }
164}