@@ -5,6 +5,8 @@ use stdsimd_test::assert_instr;
5
5
extern "unadjusted" {
6
6
#[ link_name = "llvm.x86.addcarry.64" ]
7
7
fn llvm_addcarry_u64 ( a : u8 , b : u64 , c : u64 ) -> ( u8 , u64 ) ;
8
+ #[ link_name = "llvm.x86.addcarryx.u64" ]
9
+ fn llvm_addcarryx_u64 ( a : u8 , b : u64 , c : u64 , d : * mut u8 ) -> u8 ;
8
10
#[ link_name = "llvm.x86.subborrow.64" ]
9
11
fn llvm_subborrow_u64 ( a : u8 , b : u64 , c : u64 ) -> ( u8 , u64 ) ;
10
12
}
@@ -30,7 +32,7 @@ pub unsafe fn _addcarry_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
30
32
#[ stable( feature = "simd_x86_adx" , since = "1.33.0" ) ]
31
33
#[ cfg( not( stage0) ) ]
32
34
pub unsafe fn _addcarryx_u64 ( c_in : u8 , a : u64 , b : u64 , out : & mut u64 ) -> u8 {
33
- _addcarry_u64 ( c_in, a, b, out)
35
+ llvm_addcarryx_u64 ( c_in, a, b, out as * mut _ as * mut u8 )
34
36
}
35
37
36
38
/// Add unsigned 64-bit integers a and b with unsigned 8-bit carry-in `c_in`
@@ -44,3 +46,104 @@ pub unsafe fn _subborrow_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 {
44
46
* out = b;
45
47
a
46
48
}
49
+
50
+ #[ cfg( test) ]
51
+ mod tests {
52
+ use stdsimd_test:: simd_test;
53
+
54
+ use core_arch:: x86_64:: * ;
55
+
56
+ #[ test]
57
+ fn test_addcarry_u64 ( ) {
58
+ unsafe {
59
+ let a = u64:: max_value ( ) ;
60
+ let mut out = 0 ;
61
+
62
+ let r = _addcarry_u64 ( 0 , a, 1 , & mut out) ;
63
+ assert_eq ! ( r, 1 ) ;
64
+ assert_eq ! ( out, 0 ) ;
65
+
66
+ let r = _addcarry_u64 ( 0 , a, 0 , & mut out) ;
67
+ assert_eq ! ( r, 0 ) ;
68
+ assert_eq ! ( out, a) ;
69
+
70
+ let r = _addcarry_u64 ( 1 , a, 1 , & mut out) ;
71
+ assert_eq ! ( r, 1 ) ;
72
+ assert_eq ! ( out, 1 ) ;
73
+
74
+ let r = _addcarry_u64 ( 1 , a, 0 , & mut out) ;
75
+ assert_eq ! ( r, 1 ) ;
76
+ assert_eq ! ( out, 0 ) ;
77
+
78
+ let r = _addcarry_u64 ( 0 , 3 , 4 , & mut out) ;
79
+ assert_eq ! ( r, 0 ) ;
80
+ assert_eq ! ( out, 7 ) ;
81
+
82
+ let r = _addcarry_u64 ( 1 , 3 , 4 , & mut out) ;
83
+ assert_eq ! ( r, 0 ) ;
84
+ assert_eq ! ( out, 8 ) ;
85
+ }
86
+ }
87
+
88
+ #[ simd_test( enable = "adx" ) ]
89
+ unsafe fn test_addcarryx_u64 ( ) {
90
+ let a = u64:: max_value ( ) ;
91
+ let mut out = 0 ;
92
+
93
+ let r = _addcarry_u64 ( 0 , a, 1 , & mut out) ;
94
+ assert_eq ! ( r, 1 ) ;
95
+ assert_eq ! ( out, 0 ) ;
96
+
97
+ let r = _addcarry_u64 ( 0 , a, 0 , & mut out) ;
98
+ assert_eq ! ( r, 0 ) ;
99
+ assert_eq ! ( out, a) ;
100
+
101
+ let r = _addcarry_u64 ( 1 , a, 1 , & mut out) ;
102
+ assert_eq ! ( r, 1 ) ;
103
+ assert_eq ! ( out, 1 ) ;
104
+
105
+ let r = _addcarry_u64 ( 1 , a, 0 , & mut out) ;
106
+ assert_eq ! ( r, 1 ) ;
107
+ assert_eq ! ( out, 0 ) ;
108
+
109
+ let r = _addcarry_u64 ( 0 , 3 , 4 , & mut out) ;
110
+ assert_eq ! ( r, 0 ) ;
111
+ assert_eq ! ( out, 7 ) ;
112
+
113
+ let r = _addcarry_u64 ( 1 , 3 , 4 , & mut out) ;
114
+ assert_eq ! ( r, 0 ) ;
115
+ assert_eq ! ( out, 8 ) ;
116
+ }
117
+
118
+ #[ test]
119
+ fn test_subborrow_u64 ( ) {
120
+ unsafe {
121
+ let a = u64:: max_value ( ) ;
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
+ }
149
+ }
0 commit comments