]> git.proxmox.com Git - rustc.git/blob - src/stdarch/crates/core_arch/src/x86/adx.rs
New upstream version 1.44.1+dfsg1
[rustc.git] / src / stdarch / crates / core_arch / src / x86 / adx.rs
1 #[cfg(test)]
2 use stdarch_test::assert_instr;
3
4 #[allow(improper_ctypes)]
5 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 u8) -> u8;
10 #[link_name = "llvm.x86.subborrow.32"]
11 fn llvm_subborrow_u32(a: u8, b: u32, c: u32) -> (u8, u32);
12 }
13
14 /// Adds unsigned 32-bit integers `a` and `b` with unsigned 8-bit carry-in `c_in`
15 /// (carry flag), and store the unsigned 32-bit result in `out`, and the carry-out
16 /// is returned (carry or overflow flag).
17 #[inline]
18 #[cfg_attr(test, assert_instr(adc))]
19 #[stable(feature = "simd_x86_adx", since = "1.33.0")]
20 pub unsafe fn _addcarry_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
21 let (a, b) = llvm_addcarry_u32(c_in, a, b);
22 *out = b;
23 a
24 }
25
26 /// Adds unsigned 32-bit integers `a` and `b` with unsigned 8-bit carry-in `c_in`
27 /// (carry or overflow flag), and store the unsigned 32-bit result in `out`, and
28 /// the carry-out is returned (carry or overflow flag).
29 #[inline]
30 #[target_feature(enable = "adx")]
31 #[cfg_attr(test, assert_instr(adc))]
32 #[stable(feature = "simd_x86_adx", since = "1.33.0")]
33 pub unsafe fn _addcarryx_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
34 llvm_addcarryx_u32(c_in, a, b, out as *mut _ as *mut u8)
35 }
36
37 /// Adds unsigned 32-bit integers `a` and `b` with unsigned 8-bit carry-in `c_in`
38 /// (carry or overflow flag), and store the unsigned 32-bit result in `out`, and
39 /// the carry-out is returned (carry or overflow flag).
40 #[inline]
41 #[cfg_attr(test, assert_instr(sbb))]
42 #[stable(feature = "simd_x86_adx", since = "1.33.0")]
43 pub unsafe fn _subborrow_u32(c_in: u8, a: u32, b: u32, out: &mut u32) -> u8 {
44 let (a, b) = llvm_subborrow_u32(c_in, a, b);
45 *out = b;
46 a
47 }
48
49 #[cfg(test)]
50 mod tests {
51 use stdarch_test::simd_test;
52
53 use crate::core_arch::x86::*;
54
55 #[test]
56 fn test_addcarry_u32() {
57 unsafe {
58 let a = u32::MAX;
59 let mut out = 0;
60
61 let r = _addcarry_u32(0, a, 1, &mut out);
62 assert_eq!(r, 1);
63 assert_eq!(out, 0);
64
65 let r = _addcarry_u32(0, a, 0, &mut out);
66 assert_eq!(r, 0);
67 assert_eq!(out, a);
68
69 let r = _addcarry_u32(1, a, 1, &mut out);
70 assert_eq!(r, 1);
71 assert_eq!(out, 1);
72
73 let r = _addcarry_u32(1, a, 0, &mut out);
74 assert_eq!(r, 1);
75 assert_eq!(out, 0);
76
77 let r = _addcarry_u32(0, 3, 4, &mut out);
78 assert_eq!(r, 0);
79 assert_eq!(out, 7);
80
81 let r = _addcarry_u32(1, 3, 4, &mut out);
82 assert_eq!(r, 0);
83 assert_eq!(out, 8);
84 }
85 }
86
87 #[simd_test(enable = "adx")]
88 unsafe fn test_addcarryx_u32() {
89 let a = u32::MAX;
90 let mut out = 0;
91
92 let r = _addcarryx_u32(0, a, 1, &mut out);
93 assert_eq!(r, 1);
94 assert_eq!(out, 0);
95
96 let r = _addcarryx_u32(0, a, 0, &mut out);
97 assert_eq!(r, 0);
98 assert_eq!(out, a);
99
100 let r = _addcarryx_u32(1, a, 1, &mut out);
101 assert_eq!(r, 1);
102 assert_eq!(out, 1);
103
104 let r = _addcarryx_u32(1, a, 0, &mut out);
105 assert_eq!(r, 1);
106 assert_eq!(out, 0);
107
108 let r = _addcarryx_u32(0, 3, 4, &mut out);
109 assert_eq!(r, 0);
110 assert_eq!(out, 7);
111
112 let r = _addcarryx_u32(1, 3, 4, &mut out);
113 assert_eq!(r, 0);
114 assert_eq!(out, 8);
115 }
116
117 #[simd_test(enable = "adx")]
118 unsafe fn test_addcarryx_u32_2() {
119 unsafe fn add_1_2_3() -> u32 {
120 let mut out = 0;
121 _addcarryx_u32(1, 2, 3, &mut out);
122 out
123 }
124 assert_eq!(6, add_1_2_3());
125 }
126
127 #[test]
128 fn test_subborrow_u32() {
129 unsafe {
130 let a = u32::MAX;
131 let mut out = 0;
132
133 let r = _subborrow_u32(0, 0, 1, &mut out);
134 assert_eq!(r, 1);
135 assert_eq!(out, a);
136
137 let r = _subborrow_u32(0, 0, 0, &mut out);
138 assert_eq!(r, 0);
139 assert_eq!(out, 0);
140
141 let r = _subborrow_u32(1, 0, 1, &mut out);
142 assert_eq!(r, 1);
143 assert_eq!(out, a - 1);
144
145 let r = _subborrow_u32(1, 0, 0, &mut out);
146 assert_eq!(r, 1);
147 assert_eq!(out, a);
148
149 let r = _subborrow_u32(0, 7, 3, &mut out);
150 assert_eq!(r, 0);
151 assert_eq!(out, 4);
152
153 let r = _subborrow_u32(1, 7, 3, &mut out);
154 assert_eq!(r, 0);
155 assert_eq!(out, 3);
156 }
157 }
158 }