33//! The functions in this module must only be executed on an ARM system with the CRC feature.
44
55#[ cfg_attr( not( target_arch = "aarch64" ) , allow( unused) ) ]
6+ #[ target_feature( enable = "crc" ) ]
67pub unsafe fn crc32_acle_aarch64 ( crc : u32 , buf : & [ u8 ] ) -> u32 {
78 let mut c = !crc;
89
@@ -24,29 +25,9 @@ pub unsafe fn crc32_acle_aarch64(crc: u32, buf: &[u8]) -> u32 {
2425 !c
2526}
2627
27- #[ cfg_attr( not( target_arch = "arm" ) , allow( unused) ) ]
28- pub unsafe fn crc32_acle_arm ( crc : u32 , buf : & [ u8 ] ) -> u32 {
29- let mut c = !crc;
30-
31- // SAFETY: [u8; 4] safely transmutes into u32.
32- let ( before, middle, after) = unsafe { buf. align_to :: < u32 > ( ) } ;
33-
34- c = remainder ( c, before) ;
35-
36- if middle. is_empty ( ) && after. is_empty ( ) {
37- return !c;
38- }
39-
40- for w in middle {
41- c = unsafe { __crc32w ( c, * w) } ;
42- }
43-
44- c = remainder ( c, after) ;
45-
46- !c
47- }
48-
49- fn remainder ( mut c : u32 , mut buf : & [ u8 ] ) -> u32 {
28+ #[ inline]
29+ #[ target_feature( enable = "crc" ) ]
30+ unsafe fn remainder ( mut c : u32 , mut buf : & [ u8 ] ) -> u32 {
5031 if let [ b0, b1, b2, b3, rest @ ..] = buf {
5132 c = unsafe { __crc32w ( c, u32:: from_le_bytes ( [ * b0, * b1, * b2, * b3] ) ) } ;
5233 buf = rest;
@@ -67,6 +48,9 @@ fn remainder(mut c: u32, mut buf: &[u8]) -> u32 {
6748 c
6849}
6950
51+ // FIXME the intrinsics below are stable since rust 1.80.0: remove these and use the standard
52+ // library versions once our MSRV reaches that version.
53+
7054/// CRC32 single round checksum for bytes (8 bits).
7155///
7256/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32b)
@@ -115,18 +99,6 @@ unsafe fn __crc32d(mut crc: u32, data: u64) -> u32 {
11599 }
116100}
117101
118- /// CRC32-C single round checksum for words (32 bits).
119- ///
120- /// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cw)
121- #[ target_feature( enable = "crc" ) ]
122- #[ cfg_attr( target_arch = "arm" , target_feature( enable = "v8" ) ) ]
123- pub unsafe fn __crc32cw ( mut crc : u32 , data : u32 ) -> u32 {
124- unsafe {
125- core:: arch:: asm!( "crc32cw {crc:w}, {crc:w}, {data:w}" , crc = inout( reg) crc, data = in( reg) data) ;
126- crc
127- }
128- }
129-
130102#[ cfg( test) ]
131103mod tests {
132104 use super :: * ;
@@ -142,21 +114,11 @@ mod tests {
142114
143115 a == b
144116 }
145-
146- fn crc32_acle_arm_is_crc32fast( v: Vec <u8 >, start: u32 ) -> bool {
147- let mut h = crc32fast:: Hasher :: new_with_initial( start) ;
148- h. update( & v) ;
149-
150- let a = unsafe { crc32_acle_arm( start, & v) } ;
151- let b = h. finalize( ) ;
152-
153- a == b
154- }
155117 }
156118
157119 #[ test]
158120 fn test_crc32b ( ) {
159- if !crate :: crc32 :: Crc32Fold :: is_crc_enabled ( ) {
121+ if !crate :: cpu_features :: is_enabled_crc ( ) {
160122 return ;
161123 }
162124
@@ -168,7 +130,7 @@ mod tests {
168130
169131 #[ test]
170132 fn test_crc32h ( ) {
171- if !crate :: crc32 :: Crc32Fold :: is_crc_enabled ( ) {
133+ if !crate :: cpu_features :: is_enabled_crc ( ) {
172134 return ;
173135 }
174136
@@ -180,7 +142,7 @@ mod tests {
180142
181143 #[ test]
182144 fn test_crc32w ( ) {
183- if !crate :: crc32 :: Crc32Fold :: is_crc_enabled ( ) {
145+ if !crate :: cpu_features :: is_enabled_crc ( ) {
184146 return ;
185147 }
186148
@@ -193,7 +155,7 @@ mod tests {
193155 #[ test]
194156 #[ cfg( target_arch = "aarch64" ) ]
195157 fn test_crc32d ( ) {
196- if !crate :: crc32 :: Crc32Fold :: is_crc_enabled ( ) {
158+ if !crate :: cpu_features :: is_enabled_crc ( ) {
197159 return ;
198160 }
199161
@@ -202,16 +164,4 @@ mod tests {
202164 assert_eq ! ( __crc32d( 0 , 18446744073709551615 ) , 1147535477 ) ;
203165 }
204166 }
205-
206- #[ test]
207- fn test_crc32cw ( ) {
208- if !crate :: crc32:: Crc32Fold :: is_crc_enabled ( ) {
209- return ;
210- }
211-
212- unsafe {
213- assert_eq ! ( __crc32cw( 0 , 0 ) , 0 ) ;
214- assert_eq ! ( __crc32cw( 0 , 4294967295 ) , 3080238136 ) ;
215- }
216- }
217167}
0 commit comments