@@ -18,6 +18,10 @@ extern "unadjusted" {
18
18
#[ cfg_attr( target_arch = "aarch64" , link_name = "llvm.aarch64.crc32cw" ) ]
19
19
#[ cfg_attr( target_arch = "arm" , link_name = "llvm.arm.crc32cw" ) ]
20
20
fn crc32cw_ ( crc : u32 , data : u32 ) -> u32 ;
21
+ #[ cfg_attr( target_arch = "aarch64" , link_name = "llvm.aarch64.crc32x" ) ]
22
+ fn crc32x_ ( crc : u32 , data : u64 ) -> u32 ;
23
+ #[ cfg_attr( target_arch = "aarch64" , link_name = "llvm.aarch64.crc32cx" ) ]
24
+ fn crc32cx_ ( crc : u32 , data : u64 ) -> u32 ;
21
25
}
22
26
23
27
#[ cfg( test) ]
@@ -95,12 +99,82 @@ pub unsafe fn __crc32cw(crc: u32, data: u32) -> u32 {
95
99
crc32cw_ ( crc, data)
96
100
}
97
101
102
+ /// CRC32 single round checksum for quad words (64 bits).
103
+ ///
104
+ /// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d)
105
+ #[ inline]
106
+ #[ target_feature( enable = "crc" ) ]
107
+ #[ cfg( target_arch = "aarch64" ) ]
108
+ #[ cfg_attr( test, assert_instr( crc32x) ) ]
109
+ #[ unstable( feature = "stdarch_arm_crc32" , issue = "117215" ) ]
110
+ pub unsafe fn __crc32d ( crc : u32 , data : u64 ) -> u32 {
111
+ crc32x_ ( crc, data)
112
+ }
113
+
114
+ /// CRC32 single round checksum for quad words (64 bits).
115
+ ///
116
+ /// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d)
117
+ #[ inline]
118
+ #[ target_feature( enable = "crc" ) ]
119
+ #[ cfg( target_arch = "arm" ) ]
120
+ #[ cfg_attr( test, assert_instr( crc32w) ) ]
121
+ #[ unstable( feature = "stdarch_arm_crc32" , issue = "117215" ) ]
122
+ pub unsafe fn __crc32d ( crc : u32 , data : u64 ) -> u32 {
123
+ // On 32-bit ARM this intrinsic emits a chain of two `crc32_w` instructions
124
+ // and truncates the data to 32 bits in both clang and gcc
125
+ crc32w_ (
126
+ crc32w_ ( crc, ( data & 0xffffffff ) as u32 ) ,
127
+ ( data >> 32 ) as u32 ,
128
+ )
129
+ }
130
+
131
+ /// CRC32 single round checksum for quad words (64 bits).
132
+ ///
133
+ /// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cd)
134
+ #[ inline]
135
+ #[ target_feature( enable = "crc" ) ]
136
+ #[ cfg( target_arch = "aarch64" ) ]
137
+ #[ cfg_attr( test, assert_instr( crc32cx) ) ]
138
+ #[ unstable( feature = "stdarch_arm_crc32" , issue = "117215" ) ]
139
+ pub unsafe fn __crc32cd ( crc : u32 , data : u64 ) -> u32 {
140
+ crc32cx_ ( crc, data)
141
+ }
142
+
143
+ /// CRC32 single round checksum for quad words (64 bits).
144
+ ///
145
+ /// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cd)
146
+ #[ inline]
147
+ #[ target_feature( enable = "crc" ) ]
148
+ #[ cfg( target_arch = "arm" ) ]
149
+ #[ cfg_attr( test, assert_instr( crc32cw) ) ]
150
+ #[ unstable( feature = "stdarch_arm_crc32" , issue = "117215" ) ]
151
+ pub unsafe fn __crc32cd ( crc : u32 , data : u64 ) -> u32 {
152
+ // On 32-bit ARM this intrinsic emits a chain of two `crc32_cw` instructions
153
+ // and truncates the data to 32 bits in both clang and gcc
154
+ crc32cw_ (
155
+ crc32cw_ ( crc, ( data & 0xffffffff ) as u32 ) ,
156
+ ( data >> 32 ) as u32 ,
157
+ )
158
+ }
159
+
98
160
#[ cfg( test) ]
99
161
mod tests {
100
162
use crate :: core_arch:: { arm_shared:: * , simd:: * } ;
101
163
use std:: mem;
102
164
use stdarch_test:: simd_test;
103
165
166
+ #[ simd_test( enable = "crc" ) ]
167
+ unsafe fn test_crc32d ( ) {
168
+ assert_eq ! ( __crc32d( 0 , 0 ) , 0 ) ;
169
+ assert_eq ! ( __crc32d( 0 , 18446744073709551615 ) , 1147535477 ) ;
170
+ }
171
+
172
+ #[ simd_test( enable = "crc" ) ]
173
+ unsafe fn test_crc32cd ( ) {
174
+ assert_eq ! ( __crc32cd( 0 , 0 ) , 0 ) ;
175
+ assert_eq ! ( __crc32cd( 0 , 18446744073709551615 ) , 3293575501 ) ;
176
+ }
177
+
104
178
#[ simd_test( enable = "crc" ) ]
105
179
unsafe fn test_crc32b ( ) {
106
180
assert_eq ! ( __crc32b( 0 , 0 ) , 0 ) ;
0 commit comments