@@ -18,6 +18,10 @@ extern "unadjusted" {
1818 #[ cfg_attr( target_arch = "aarch64" , link_name = "llvm.aarch64.crc32cw" ) ]
1919 #[ cfg_attr( target_arch = "arm" , link_name = "llvm.arm.crc32cw" ) ]
2020 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 ;
2125}
2226
2327#[ cfg( test) ]
@@ -95,12 +99,82 @@ pub unsafe fn __crc32cw(crc: u32, data: u32) -> u32 {
9599 crc32cw_ ( crc, data)
96100}
97101
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+
98160#[ cfg( test) ]
99161mod tests {
100162 use crate :: core_arch:: { arm_shared:: * , simd:: * } ;
101163 use std:: mem;
102164 use stdarch_test:: simd_test;
103165
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+
104178 #[ simd_test( enable = "crc" ) ]
105179 unsafe fn test_crc32b ( ) {
106180 assert_eq ! ( __crc32b( 0 , 0 ) , 0 ) ;
0 commit comments