5
5
//! It dispatches to the appropriate architecture-specific implementation
6
6
//! based on the target architecture.
7
7
8
+ #[ cfg( target_arch = "aarch64" ) ]
9
+ use std:: arch:: is_aarch64_feature_detected;
10
+
8
11
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" , target_arch = "aarch64" ) ) ]
9
12
use crate :: algorithm;
10
13
@@ -14,13 +17,14 @@ use crate::structs::CrcParams;
14
17
use crate :: structs:: { Width32 , Width64 } ;
15
18
16
19
#[ cfg( target_arch = "aarch64" ) ]
17
- use crate :: arch :: aarch64:: AArch64Ops ;
20
+ use aarch64:: AArch64Ops ;
18
21
19
22
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
20
- use crate :: arch :: x86:: X86Ops ;
23
+ use x86:: X86Ops ;
21
24
22
- #[ cfg( all( target_arch = "x86_64" , feature = "vpclmulqdq" ) ) ]
23
- use crate :: arch:: vpclmulqdq:: Vpclmulqdq512Ops ;
25
+ #[ cfg( target_arch = "x86_64" ) ]
26
+ #[ rustversion:: since( 1.89 ) ]
27
+ use vpclmulqdq:: Vpclmulqdq512Ops ;
24
28
25
29
mod aarch64;
26
30
mod software;
@@ -33,84 +37,118 @@ mod x86;
33
37
/// # Safety
34
38
/// May use native CPU features
35
39
#[ inline]
36
- #[ cfg_attr(
37
- any( target_arch = "x86" , target_arch = "x86_64" ) ,
38
- target_feature( enable = "sse2,sse4.1,pclmulqdq" )
39
- ) ]
40
- #[ cfg_attr(
41
- all( target_arch = "x86_64" , feature = "vpclmulqdq" ) ,
42
- target_feature( enable = "avx2,vpclmulqdq,avx512f,avx512vl" )
43
- ) ]
44
- #[ cfg_attr( target_arch = "aarch64" , target_feature( enable = "neon,aes" ) ) ]
40
+ #[ cfg( target_arch = "aarch64" ) ]
41
+ #[ target_feature( enable = "neon,aes" ) ]
45
42
pub ( crate ) unsafe fn update ( state : u64 , bytes : & [ u8 ] , params : CrcParams ) -> u64 {
46
- #[ cfg( target_arch = "aarch64" ) ]
47
- {
48
- let ops = AArch64Ops ;
43
+ let ops = AArch64Ops ;
49
44
50
- match params. width {
51
- 64 => algorithm:: update :: < AArch64Ops , Width64 > ( state, bytes, params, & ops) ,
52
- 32 => {
53
- algorithm:: update :: < AArch64Ops , Width32 > ( state as u32 , bytes, params, & ops) as u64
54
- }
55
- _ => panic ! ( "Unsupported CRC width: {}" , params. width) ,
56
- }
45
+ match params. width {
46
+ 64 => algorithm:: update :: < AArch64Ops , Width64 > ( state, bytes, params, & ops) ,
47
+ 32 => algorithm:: update :: < AArch64Ops , Width32 > ( state as u32 , bytes, params, & ops) as u64 ,
48
+ _ => panic ! ( "Unsupported CRC width: {}" , params. width) ,
57
49
}
50
+ }
58
51
59
- #[ cfg( all( target_arch = "x86_64" , feature = "vpclmulqdq" ) ) ]
60
- {
61
- use std:: arch:: is_x86_feature_detected;
62
-
63
- if bytes. len ( ) >= 256 && is_x86_feature_detected ! ( "vpclmulqdq" ) {
64
- let ops = Vpclmulqdq512Ops :: new ( ) ;
65
-
66
- return match params. width {
67
- 64 => algorithm:: update :: < Vpclmulqdq512Ops , Width64 > ( state, bytes, params, & ops) ,
68
- 32 => algorithm:: update :: < Vpclmulqdq512Ops , Width32 > (
69
- state as u32 ,
70
- bytes,
71
- params,
72
- & ops,
73
- ) as u64 ,
74
- _ => panic ! ( "Unsupported CRC width: {}" , params. width) ,
75
- } ;
76
- }
52
+ #[ rustversion:: before( 1.89 ) ]
53
+ #[ inline]
54
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
55
+ #[ target_feature( enable = "sse2,sse4.1,pclmulqdq" ) ]
56
+ pub ( crate ) unsafe fn update ( state : u64 , bytes : & [ u8 ] , params : CrcParams ) -> u64 {
57
+ let ops = X86Ops ;
58
+
59
+ match params. width {
60
+ 64 => algorithm:: update :: < X86Ops , Width64 > ( state, bytes, params, & ops) ,
61
+ 32 => algorithm:: update :: < X86Ops , Width32 > ( state as u32 , bytes, params, & ops) as u64 ,
62
+ _ => panic ! ( "Unsupported CRC width: {}" , params. width) ,
77
63
}
64
+ }
78
65
79
- #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
80
- {
81
- let ops = X86Ops ;
66
+ #[ rustversion:: since( 1.89 ) ]
67
+ #[ inline]
68
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
69
+ #[ target_feature( enable = "sse2,sse4.1,pclmulqdq" ) ]
70
+ pub ( crate ) unsafe fn update ( state : u64 , bytes : & [ u8 ] , params : CrcParams ) -> u64 {
71
+ use std:: arch:: is_x86_feature_detected;
72
+
73
+ if bytes. len ( ) >= 256 && is_x86_feature_detected ! ( "vpclmulqdq" ) {
74
+ let ops = Vpclmulqdq512Ops :: new ( ) ;
82
75
83
- match params. width {
84
- 64 => algorithm:: update :: < X86Ops , Width64 > ( state, bytes, params, & ops) ,
85
- 32 => algorithm:: update :: < X86Ops , Width32 > ( state as u32 , bytes, params, & ops) as u64 ,
76
+ return match params. width {
77
+ 64 => algorithm:: update :: < Vpclmulqdq512Ops , Width64 > ( state, bytes, params, & ops) ,
78
+ 32 => algorithm:: update :: < Vpclmulqdq512Ops , Width32 > ( state as u32 , bytes, params, & ops)
79
+ as u64 ,
86
80
_ => panic ! ( "Unsupported CRC width: {}" , params. width) ,
81
+ } ;
82
+ }
83
+
84
+ // fallback to the standard x86 SSE implementation
85
+
86
+ let ops = X86Ops ;
87
+
88
+ match params. width {
89
+ 64 => algorithm:: update :: < X86Ops , Width64 > ( state, bytes, params, & ops) ,
90
+ 32 => algorithm:: update :: < X86Ops , Width32 > ( state as u32 , bytes, params, & ops) as u64 ,
91
+ _ => panic ! ( "Unsupported CRC width: {}" , params. width) ,
92
+ }
93
+ }
94
+
95
+ #[ inline]
96
+ #[ cfg( all(
97
+ not( target_arch = "x86" ) ,
98
+ not( target_arch = "x86_64" ) ,
99
+ not( target_arch = "aarch64" )
100
+ ) ) ]
101
+ pub ( crate ) unsafe fn update ( state : u64 , bytes : & [ u8 ] , params : CrcParams ) -> u64 {
102
+ software:: update ( state, bytes, params)
103
+ }
104
+
105
+ #[ rustversion:: before( 1.89 ) ]
106
+ pub fn get_target ( ) -> String {
107
+ #[ cfg( target_arch = "aarch64" ) ]
108
+ {
109
+ if is_aarch64_feature_detected ! ( "sha3" ) {
110
+ return "aarch64-neon-eor3-pclmulqdq" . to_string ( ) ;
87
111
}
112
+
113
+ "aarch64-neon-pclmulqdq" . to_string ( )
88
114
}
89
115
90
- #[ cfg( not( any( target_arch = "x86" , target_arch = "x86_64" , target_arch = "aarch64" ) ) ) ]
91
- return software:: update ( state, bytes, params) ;
116
+ #[ allow( unreachable_code) ]
117
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
118
+ return "x86-sse-pclmulqdq" . to_string ( ) ;
119
+
120
+ #[ cfg( not( any( target_arch = "aarch64" , target_arch = "x86" , target_arch = "x86_64" ) ) ) ]
121
+ return "software-fallback-tables" . to_string ( ) ;
92
122
}
93
123
124
+ #[ rustversion:: since( 1.89 ) ]
94
125
pub fn get_target ( ) -> String {
95
- #[ cfg( all( target_arch = "aarch64" , target_feature = "sha3" ) ) ]
96
- return "internal-aarch64-neon-eor3" . to_string ( ) ;
126
+ #[ cfg( target_arch = "aarch64" ) ]
127
+ {
128
+ if is_aarch64_feature_detected ! ( "sha3" ) {
129
+ return "aarch64-neon-eor3-pclmulqdq" . to_string ( ) ;
130
+ }
97
131
98
- # [ cfg ( all ( target_arch = "aarch64" , not ( target_feature = "sha3" ) ) ) ]
99
- return "internal-aarch64-neon" . to_string ( ) ;
132
+ "aarch64-neon-pclmulqdq" . to_string ( )
133
+ }
100
134
101
- #[ cfg( all ( target_arch = "x86_64" , feature = "vpclmulqdq" ) ) ]
135
+ #[ cfg( target_arch = "x86_64" ) ]
102
136
{
103
137
if is_x86_feature_detected ! ( "vpclmulqdq" ) {
104
- return "internal-x86_64-avx512-vpclmulqdq" . to_string ( ) ;
138
+ return "x86_64-avx512-vpclmulqdq" . to_string ( ) ;
139
+ }
140
+
141
+ if is_x86_feature_detected ! ( "avx2" ) {
142
+ return "x86_64-avx2-pclmulqdq" . to_string ( ) ;
105
143
}
106
144
}
107
145
108
146
#[ allow( unreachable_code) ]
109
147
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
110
- return "internal- x86-sse-pclmulqdq" . to_string ( ) ;
148
+ return "x86-sse-pclmulqdq" . to_string ( ) ;
111
149
112
150
#[ cfg( not( any( target_arch = "aarch64" , target_arch = "x86" , target_arch = "x86_64" ) ) ) ]
113
- return "software-fallback" . to_string ( ) ;
151
+ return "software-fallback-tables " . to_string ( ) ;
114
152
}
115
153
116
154
#[ cfg( test) ]
0 commit comments