zenjxl_decoder_simd/x86_64/
mod.rs1#![allow(clippy::identity_op)]
7
8#[cfg(feature = "avx")]
9pub(super) mod avx;
10#[cfg(feature = "avx512")]
11pub(super) mod avx512;
12#[cfg(feature = "sse42")]
13pub(super) mod sse42;
14
15#[macro_export]
16macro_rules! simd_function {
17 (
18 $dname:ident,
19 $descr:ident: $descr_ty:ident,
20 $(#[$($attr:meta)*])*
21 $pub:vis fn $name:ident($($arg:ident: $ty:ty),* $(,)?) $(-> $ret:ty )? $body: block
22 ) => {
23 #[inline(always)]
24 $(#[$($attr)*])*
25 $pub fn $name<$descr_ty: $crate::SimdDescriptor>($descr: $descr_ty, $($arg: $ty),*) $(-> $ret)? $body
26
27 paste::paste! {
28 #[cfg(all(target_arch = "x86_64", feature = "avx512"))]
29 #[$crate::__arcane]
30 $(#[$($attr)*])*
31 fn [<$dname __v4>](_token: $crate::X64V4Token, $($arg: $ty),*) $(-> $ret)? {
32 $name($crate::Avx512Descriptor::from_token(_token), $($arg),*)
33 }
34
35 #[cfg(all(target_arch = "x86_64", feature = "avx"))]
36 #[$crate::__arcane]
37 $(#[$($attr)*])*
38 fn [<$dname __v3>](_token: $crate::X64V3Token, $($arg: $ty),*) $(-> $ret)? {
39 $name($crate::AvxDescriptor::from_token(_token), $($arg),*)
40 }
41
42 #[cfg(all(target_arch = "x86_64", feature = "sse42"))]
43 #[$crate::__arcane]
44 $(#[$($attr)*])*
45 fn [<$dname __v2>](_token: $crate::X64V2Token, $($arg: $ty),*) $(-> $ret)? {
46 $name($crate::Sse42Descriptor::from_token(_token), $($arg),*)
47 }
48
49 $(#[$($attr)*])*
50 fn [<$dname __scalar>](_token: $crate::ScalarToken, $($arg: $ty),*) $(-> $ret)? {
51 $name($crate::ScalarDescriptor::from_token(_token), $($arg),*)
52 }
53
54 $(#[$($attr)*])*
55 $pub fn $dname($($arg: $ty),*) $(-> $ret)? {
56 use $crate::__SimdToken;
57 #[cfg(all(target_arch = "x86_64", feature = "avx512"))]
58 if let Some(t) = $crate::X64V4Token::summon() {
59 return [<$dname __v4>](t, $($arg),*);
60 }
61 #[cfg(all(target_arch = "x86_64", feature = "avx"))]
62 if let Some(t) = $crate::X64V3Token::summon() {
63 return [<$dname __v3>](t, $($arg),*);
64 }
65 #[cfg(all(target_arch = "x86_64", feature = "sse42"))]
66 if let Some(t) = $crate::X64V2Token::summon() {
67 return [<$dname __v2>](t, $($arg),*);
68 }
69 [<$dname __scalar>]($crate::ScalarToken::summon().unwrap(), $($arg),*)
70 }
71 }
72 };
73}
74
75#[macro_export]
76macro_rules! test_all_instruction_sets {
77 (
78 $name:ident
79 ) => {
80 paste::paste! {
81 #[test]
82 fn [<$name _scalar>]() {
83 use $crate::SimdDescriptor;
84 $name($crate::ScalarDescriptor::new().unwrap())
85 }
86 }
87
88 $crate::test_sse42!($name);
89 $crate::test_avx!($name);
90 $crate::test_avx512!($name);
91 };
92}
93
94#[cfg(feature = "sse42")]
95#[doc(hidden)]
96#[macro_export]
97macro_rules! test_sse42 {
98 ($name:ident) => {
99 paste::paste! {
100 #[test]
101 fn [<$name _sse42>]() {
102 use $crate::__SimdToken;
103 let Some(token) = $crate::X64V2Token::summon() else { return; };
104 #[$crate::__arcane]
105 fn inner(token: $crate::X64V2Token) {
106 $name($crate::Sse42Descriptor::from_token(token))
107 }
108 inner(token);
109 }
110 }
111 };
112}
113
114#[cfg(feature = "avx")]
115#[doc(hidden)]
116#[macro_export]
117macro_rules! test_avx {
118 ($name:ident) => {
119 paste::paste! {
120 #[test]
121 fn [<$name _avx>]() {
122 use $crate::__SimdToken;
123 let Some(token) = $crate::X64V3Token::summon() else { return; };
124 #[$crate::__arcane]
125 fn inner(token: $crate::X64V3Token) {
126 $name($crate::AvxDescriptor::from_token(token))
127 }
128 inner(token);
129 }
130 }
131 };
132}
133
134#[cfg(feature = "avx512")]
135#[doc(hidden)]
136#[macro_export]
137macro_rules! test_avx512 {
138 ($name:ident) => {
139 paste::paste! {
140 #[test]
141 fn [<$name _avx512>]() {
142 use $crate::__SimdToken;
143 let Some(token) = $crate::X64V4Token::summon() else { return; };
144 #[$crate::__arcane]
145 fn inner(token: $crate::X64V4Token) {
146 $name($crate::Avx512Descriptor::from_token(token))
147 }
148 inner(token);
149 }
150 }
151 };
152}
153
154#[cfg(not(feature = "sse42"))]
155#[doc(hidden)]
156#[macro_export]
157macro_rules! test_sse42 {
158 ($name:ident) => {};
159}
160
161#[cfg(not(feature = "avx"))]
162#[doc(hidden)]
163#[macro_export]
164macro_rules! test_avx {
165 ($name:ident) => {};
166}
167
168#[cfg(not(feature = "avx512"))]
169#[doc(hidden)]
170#[macro_export]
171macro_rules! test_avx512 {
172 ($name:ident) => {};
173}
174
175#[macro_export]
176macro_rules! bench_all_instruction_sets {
177 (
178 $name:ident,
179 $criterion:ident
180 ) => {
181 #[allow(unused)]
182 use $crate::SimdDescriptor;
183 $crate::bench_avx512!($name, $criterion);
184 $crate::bench_avx!($name, $criterion);
185 $crate::bench_sse42!($name, $criterion);
186 $name(
187 $crate::ScalarDescriptor::new().unwrap(),
188 $criterion,
189 "scalar",
190 );
191 };
192}
193
194#[cfg(feature = "avx512")]
195#[doc(hidden)]
196#[macro_export]
197macro_rules! bench_avx512 {
198 ($name:ident, $criterion:ident) => {
199 if let Some(d) = $crate::Avx512Descriptor::new() {
200 d.call(|d| $name(d, $criterion, "avx512"));
201 }
202 };
203}
204
205#[cfg(feature = "avx")]
206#[doc(hidden)]
207#[macro_export]
208macro_rules! bench_avx {
209 ($name:ident, $criterion:ident) => {
210 if let Some(d) = $crate::AvxDescriptor::new() {
211 d.call(|d| $name(d, $criterion, "avx"));
212 }
213 };
214}
215
216#[cfg(feature = "sse42")]
217#[doc(hidden)]
218#[macro_export]
219macro_rules! bench_sse42 {
220 ($name:ident, $criterion:ident) => {
221 if let Some(d) = $crate::Sse42Descriptor::new() {
222 d.call(|d| $name(d, $criterion, "sse42"));
223 }
224 };
225}
226
227#[cfg(not(feature = "avx512"))]
228#[doc(hidden)]
229#[macro_export]
230macro_rules! bench_avx512 {
231 ($name:ident, $criterion:ident) => {};
232}
233
234#[cfg(not(feature = "avx"))]
235#[doc(hidden)]
236#[macro_export]
237macro_rules! bench_avx {
238 ($name:ident, $criterion:ident) => {};
239}
240
241#[cfg(not(feature = "sse42"))]
242#[doc(hidden)]
243#[macro_export]
244macro_rules! bench_sse42 {
245 ($name:ident, $criterion:ident) => {};
246}