1#![cfg_attr(not(feature = "simd"), no_std)]
2#![cfg_attr(feature = "simd", feature(portable_simd))]
3#![cfg_attr(target_arch = "arm", feature(stdsimd, arm_target_feature))]
4#![cfg_attr(target_arch = "aarch64", feature(stdsimd, aarch64_target_feature))]
5
6pub mod portable;
7
8#[cfg(feature = "simd")]
9mod simd128;
10
11#[cfg(feature = "simd")]
12mod simd256;
13
14#[cfg(feature = "simd")]
15#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
16mod ssse3;
17
18#[cfg(feature = "simd")]
19#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
20mod avx2;
21
22#[cfg(feature = "simd")]
23#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
24mod neon;
25
26pub const SIZE: usize = 12;
27
28pub fn gimli(state: &mut [u32; SIZE]) {
29 #[cfg(feature = "simd")]
30 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
31 unsafe {
32 if is_x86_feature_detected!("ssse3") {
33 return ssse3::gimli(state);
34 }
35 }
36
37 #[cfg(feature = "simd")]
38 #[cfg(target_arch = "arm")]
39 unsafe {
40 if is_arm_feature_detected!("neon") {
41 return neon::gimli(state);
42 }
43 }
44
45 #[cfg(feature = "simd")]
46 #[cfg(target_arch = "aarch64")]
47 unsafe {
48 if is_aarch64_feature_detected!("neon") {
49 return neon::gimli(state);
50 }
51 }
52
53 #[cfg(feature = "simd")] {
54 simd128::gimli::<()>(state)
55 }
56
57 #[cfg(not(feature = "simd"))] {
58 portable::gimli(state)
59 }
60}
61
62pub fn gimli_x2(state: &mut [u32; SIZE], state2: &mut [u32; SIZE]) {
63 #[cfg(feature = "simd")]
64 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
65 unsafe {
66 if is_x86_feature_detected!("avx2") {
67 return avx2::gimli_x2(state, state2);
68 }
69 }
70
71 #[cfg(feature = "simd")] {
72 simd256::gimli_x2::<()>(state, state2);
73 }
74
75 #[cfg(not(feature = "simd"))] {
76 gimli(state);
77 gimli(state2);
78 }
79}
80
81#[inline]
82pub fn state_with<F>(state: &mut [u32; SIZE], f: F)
83 where F: FnOnce(&mut [u8; SIZE * 4])
84{
85 #[inline]
86 fn transmute(arr: &mut [u32; SIZE]) -> &mut [u8; SIZE * 4] {
87 unsafe { &mut *(arr as *mut [u32; SIZE] as *mut [u8; SIZE * 4]) }
91 }
92
93 #[cfg(target_endian = "big")]
94 for n in state.iter_mut() {
95 *n = n.to_le();
96 }
97
98 f(transmute(state));
99
100 #[cfg(target_endian = "big")]
101 for n in state.iter_mut() {
102 *n = n.to_le();
103 }
104}
105
106#[cfg(gimli_test)]
107pub mod test {
108 #[cfg(feature = "simd")]
109 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
110 pub use crate::ssse3::gimli as ssse3_gimli;
111
112 #[cfg(feature = "simd")]
113 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
114 pub use crate::avx2::gimli_x2 as avx2_gimli_x2;
115
116 #[cfg(feature = "simd")]
117 #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
118 pub use crate::neon::gimli as neon_gimli;
119
120 #[cfg(feature = "simd")]
121 pub use crate::simd128::gimli as simd128_gimli;
122
123 #[cfg(feature = "simd")]
124 pub use crate::simd256::gimli_x2 as simd256_gimli_x2;
125}