1#![doc = include_str!("../docs/readme.md")]
5#![no_std]
7#![deny(unsafe_code)]
9#![cfg_attr(not(any(test, doc)), forbid(unsafe_code))]
10#![cfg_attr(feature = "maint-code", deny(warnings))]
12#![cfg_attr(not(test), warn(missing_docs, clippy::missing_docs_in_private_items))]
14#![cfg_attr(
16 not(feature = "maint-lints"),
17 allow(unknown_lints, renamed_and_removed_lints)
18)]
19
20#[cfg(doc)]
22extern crate std;
23
24#[doc = include_str!("../docs/target_feature_dispatch.md")]
25#[macro_export]
26macro_rules! target_feature_dispatch {
27 ($(#[$($pseudo_meta: tt)+])* $(if $($arch: tt $(($arch_arg: tt))?)||+ { $($if: tt)* })else+ else { $($else: tt)* }) => {
35 $crate::target_feature_dispatch!(
36 @__tgtfeat_dispatch_parse_options
37 (any(), any(), all())
38 $(#[$($pseudo_meta)+])*
39 ($($else)*) $((($($arch$(($arch_arg))?)||+) ($($if)*)))+
40 )
41 };
42
43 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[dynamic] $($rest: tt)+) => {
48 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_parse_options (all(), $nightly, $dispatch) $($rest)+)
49 };
50 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[static] $($rest: tt)+) => {
52 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_parse_options (any(), $nightly, $dispatch) $($rest)+)
53 };
54 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[unstable] $($rest: tt)+) => {
56 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_parse_options ($dyn, all(), $dispatch) $($rest)+)
57 };
58 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[stable] $($rest: tt)+) => {
60 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_parse_options ($dyn, any(), $dispatch) $($rest)+)
61 };
62 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[cfg_attr($meta: meta, dynamic)] $($rest: tt)+) => {
64 $crate::target_feature_dispatch!(
65 @__tgtfeat_dispatch_parse_options
66 (any($dyn, $meta), $nightly, $dispatch)
67 $($rest)+
68 )
69 };
70 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[cfg_attr($meta: meta, static)] $($rest: tt)+) => {
72 $crate::target_feature_dispatch!(
73 @__tgtfeat_dispatch_parse_options
74 (all($dyn, not($meta)), $nightly, $dispatch)
75 $($rest)+
76 )
77 };
78 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[cfg_attr($meta: meta, unstable)] $($rest: tt)+) => {
80 $crate::target_feature_dispatch!(
81 @__tgtfeat_dispatch_parse_options
82 ($dyn, any($nightly, $meta), $dispatch)
83 $($rest)+
84 )
85 };
86 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[cfg_attr($meta: meta, stable)] $($rest: tt)+) => {
88 $crate::target_feature_dispatch!(
89 @__tgtfeat_dispatch_parse_options
90 ($dyn, all($nightly, not($meta)), $dispatch)
91 $($rest)+
92 )
93 };
94 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[cfg_non_fallback($meta: meta)] $($rest: tt)+) => {
96 $crate::target_feature_dispatch!(
97 @__tgtfeat_dispatch_parse_options
98 ($dyn, $nightly, all($dispatch, $meta))
99 $($rest)+
100 )
101 };
102 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) #[$($pmeta: tt)+] $($rest: tt)+) => {
104 compile_error!(concat!("invalid pseudo-attribute: ", stringify!(#[$($pmeta)+])));
105 };
106 (@__tgtfeat_dispatch_parse_options ($dyn: meta, $nightly: meta, $dispatch: meta) ($($else: tt)*) $(($($ifs: tt)+))+) => {
108 {
109 #[cfg($dispatch)]
110 {
111 $crate::target_feature_dispatch!(
112 @__tgtfeat_dispatch_arch_chain ($dyn, $nightly)
113 ($($else)*) $(($($ifs)+))+
114 )
115 }
116 #[cfg(not($dispatch))]
117 {
118 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($else)*)
119 }
120 }
121 };
122
123 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) ((family("aarch64")) ($($if: tt)*)) $($rest: tt)*) => {
129 {
130 #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
131 {
132 $crate::target_feature_dispatch!(
133 @__tgtfeat_dispatch_arch_clause (family("aarch64")) ($($opts),*)
134 ($($else)*) ($($if)*)
135 )
136 }
137 #[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))]
138 {
139 $crate::target_feature_dispatch!(
140 @__tgtfeat_dispatch_arch_chain ($($opts),*)
141 ($($else)*) $($rest)*
142 )
143 }
144 }
145 };
146 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) ((family("riscv")) ($($if: tt)*)) $($rest: tt)*) => {
148 {
149 #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
150 {
151 $crate::target_feature_dispatch!(
152 @__tgtfeat_dispatch_arch_clause (family("riscv")) ($($opts),*)
153 ($($else)*) ($($if)*)
154 )
155 }
156 #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
157 {
158 $crate::target_feature_dispatch!(
159 @__tgtfeat_dispatch_arch_chain ($($opts),*)
160 ($($else)*) $($rest)*
161 )
162 }
163 }
164 };
165 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) ((family("x86")) ($($if: tt)*)) $($rest: tt)*) => {
167 {
168 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
169 {
170 $crate::target_feature_dispatch!(
171 @__tgtfeat_dispatch_arch_clause (family("x86")) ($($opts),*)
172 ($($else)*) ($($if)*)
173 )
174 }
175 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
176 {
177 $crate::target_feature_dispatch!(
178 @__tgtfeat_dispatch_arch_chain ($($opts),*)
179 ($($else)*) $($rest)*
180 )
181 }
182 }
183 };
184 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) ((class("arm")) ($($if: tt)*)) $($rest: tt)*) => {
186 {
187 #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "arm"))]
188 {
189 $crate::target_feature_dispatch!(
190 @__tgtfeat_dispatch_arch_clause (class("arm")) ($($opts),*)
191 ($($else)*) ($($if)*)
192 )
193 }
194 #[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "arm")))]
195 {
196 $crate::target_feature_dispatch!(
197 @__tgtfeat_dispatch_arch_chain ($($opts),*)
198 ($($else)*) $($rest)*
199 )
200 }
201 }
202 };
203 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) ((class("mips")) ($($if: tt)*)) $($rest: tt)*) => {
205 {
206 #[cfg(any(target_arch = "mips", target_arch = "mips64", target_arch = "mips32r6", target_arch = "mips64r6"))]
207 {
208 $crate::target_feature_dispatch!(
209 @__tgtfeat_dispatch_arch_clause (class("mips")) ($($opts),*)
210 ($($else)*) ($($if)*)
211 )
212 }
213 #[cfg(not(any(target_arch = "mips", target_arch = "mips64", target_arch = "mips32r6", target_arch = "mips64r6")))]
214 {
215 $crate::target_feature_dispatch!(
216 @__tgtfeat_dispatch_arch_chain ($($opts),*)
217 ($($else)*) $($rest)*
218 )
219 }
220 }
221 };
222 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) ((class("mips-classic")) ($($if: tt)*)) $($rest: tt)*) => {
224 {
225 #[cfg(any(target_arch = "mips", target_arch = "mips64"))]
226 {
227 $crate::target_feature_dispatch!(
228 @__tgtfeat_dispatch_arch_clause (class("mips-classic")) ($($opts),*)
229 ($($else)*) ($($if)*)
230 )
231 }
232 #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
233 {
234 $crate::target_feature_dispatch!(
235 @__tgtfeat_dispatch_arch_chain ($($opts),*)
236 ($($else)*) $($rest)*
237 )
238 }
239 }
240 };
241 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) ((class("powerpc")) ($($if: tt)*)) $($rest: tt)*) => {
243 {
244 #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
245 {
246 $crate::target_feature_dispatch!(
247 @__tgtfeat_dispatch_arch_clause (class("powerpc")) ($($opts),*)
248 ($($else)*) ($($if)*)
249 )
250 }
251 #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
252 {
253 $crate::target_feature_dispatch!(
254 @__tgtfeat_dispatch_arch_chain ($($opts),*)
255 ($($else)*) $($rest)*
256 )
257 }
258 }
259 };
260 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) ((class("sparc")) ($($if: tt)*)) $($rest: tt)*) => {
262 {
263 #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))]
264 {
265 $crate::target_feature_dispatch!(
266 @__tgtfeat_dispatch_arch_clause (class("sparc")) ($($opts),*)
267 ($($else)*) ($($if)*)
268 )
269 }
270 #[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))]
271 {
272 $crate::target_feature_dispatch!(
273 @__tgtfeat_dispatch_arch_chain ($($opts),*)
274 ($($else)*) $($rest)*
275 )
276 }
277 }
278 };
279 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) ((class("wasm")) ($($if: tt)*)) $($rest: tt)*) => {
281 {
282 #[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))]
283 {
284 $crate::target_feature_dispatch!(
285 @__tgtfeat_dispatch_arch_clause (class("wasm")) ($($opts),*)
286 ($($else)*) ($($if)*)
287 )
288 }
289 #[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
290 {
291 $crate::target_feature_dispatch!(
292 @__tgtfeat_dispatch_arch_chain ($($opts),*)
293 ($($else)*) $($rest)*
294 )
295 }
296 }
297 };
298 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) (($($arch: tt $(($arch_arg: tt))?)||+) ($($if: tt)*)) $($rest: tt)*) => {
300 $crate::target_feature_dispatch!(
301 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
302 (() ($($arch$(($arch_arg))?)||+) ($($if)*)) $($rest)*
303 )
304 };
305 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*)) => {
307 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($else)*)
308 };
309
310 (
316 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
317 (($($added: tt,)*) (family("aarch64") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
318 ) => {
319 $crate::target_feature_dispatch!(
320 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
321 (($($added,)* "aarch64", "arm64ec",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
322 $($rest)*
323 )
324 };
325 (
327 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
328 (($($added: tt,)*) (family("riscv") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
329 ) => {
330 $crate::target_feature_dispatch!(
331 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
332 (($($added,)* "riscv32", "riscv64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
333 $($rest)*
334 )
335 };
336 (
338 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
339 (($($added: tt,)*) (family("x86") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
340 ) => {
341 $crate::target_feature_dispatch!(
342 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
343 (($($added,)* "x86", "x86_64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
344 $($rest)*
345 )
346 };
347 (
349 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
350 (($($added: tt,)*) (class("arm") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
351 ) => {
352 $crate::target_feature_dispatch!(
353 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
354 (($($added,)* "aarch64", "arm64ec", "arm",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
355 $($rest)*
356 )
357 };
358 (
360 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
361 (($($added: tt,)*) (class("mips") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
362 ) => {
363 $crate::target_feature_dispatch!(
364 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
365 (($($added,)* "mips", "mips64", "mips32r6", "mips64r6",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
366 $($rest)*
367 )
368 };
369 (
371 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
372 (($($added: tt,)*) (class("mips-classic") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
373 ) => {
374 $crate::target_feature_dispatch!(
375 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
376 (($($added,)* "mips", "mips64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
377 $($rest)*
378 )
379 };
380 (
382 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
383 (($($added: tt,)*) (class("powerpc") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
384 ) => {
385 $crate::target_feature_dispatch!(
386 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
387 (($($added,)* "powerpc", "powerpc64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
388 $($rest)*
389 )
390 };
391 (
393 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
394 (($($added: tt,)*) (class("sparc") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
395 ) => {
396 $crate::target_feature_dispatch!(
397 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
398 (($($added,)* "sparc", "sparc64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
399 $($rest)*
400 )
401 };
402 (
404 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
405 (($($added: tt,)*) (class("wasm") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
406 ) => {
407 $crate::target_feature_dispatch!(
408 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
409 (($($added,)* "wasm32", "wasm64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
410 $($rest)*
411 )
412 };
413 (
415 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
416 (($($added: tt,)*) ($arch1: tt ($arch1_arg: tt) $(|| $($arch2: tt$(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
417 ) => {
418 compile_error!(concat!("Invalid architecture specifier: ", stringify!($arch1($arch1_arg))));
419 };
420 (
421 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
422 (($($added: tt,)*) ($arch1: tt $(|| $($arch2: tt$(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
423 ) => {
424 $crate::target_feature_dispatch!(
425 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
426 (($($added,)* $arch1,) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
427 $($rest)*
428 )
429 };
430 (
432 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
433 (($($added: tt,)+) () ($($if: tt)*)) $($rest: tt)*
434 ) => {
435 {
436 #[cfg(any($(target_arch = $added),+))]
437 {
438 $crate::target_feature_dispatch!(
439 @__tgtfeat_dispatch_arch_clause ($($added)||+) ($($opts),*)
440 ($($else)*) ($($if)*)
441 )
442 }
443 #[cfg(not(any($(target_arch = $added),+)))]
444 {
445 $crate::target_feature_dispatch!(
446 @__tgtfeat_dispatch_arch_chain ($($opts),*)
447 ($($else)*) $($rest)*
448 )
449 }
450 }
451 };
452
453 (
473 @__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*)
474 ($(if $($feat: tt)&&+ { $($if: tt)* })else+)
475 ) => {
476 $crate::target_feature_dispatch!(
477 @__tgtfeat_dispatch_feat_chain_entry
478 ($($arch$(($arch_arg))?)||+) ($($opts),*)
479 ($($else1)*) (@__tgtfeat_dispatch_no_fallback)
480 $((($($feat)&&+) ($($if)*)))+
481 )
482 };
483 (
485 @__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*)
486 ($(if $($feat: tt)&&+ { $($if: tt)* })else+ else { @__tgtfeat_dispatch_no_fallback })
487 ) => {
488 compile_error!("invalid feature-specific `else` clause");
489 };
490 (
492 @__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*)
493 ($(if $($feat: tt)&&+ { $($if: tt)* })else+ else { $($else2: tt)* })
494 ) => {
495 $crate::target_feature_dispatch!(
496 @__tgtfeat_dispatch_feat_chain_entry
497 ($($arch$(($arch_arg))?)||+) ($($opts),*)
498 ($($else2)*) ($($else2)*)
499 $((($($feat)&&+) ($($if)*)))+
500 )
501 };
502 (@__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*) (($expr: expr))) => {
504 $expr
505 };
506 (@__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*) ({$($tt: tt)*})) => {
508 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($tt)*)
509 };
510 (@__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*) ()) => {
512 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr ())
513 };
514 (@__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*) ($($tt: tt)*)) => {
516 compile_error!("unsupported or invalid architecture clause");
517 };
518
519 (@__tgtfeat_dispatch_feat_chain_entry (family("aarch64")) ($($opts: meta),*) $($rest: tt)+) => {
529 $crate::target_feature_dispatch!(
530 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
531 (::std::arch::is_aarch64_feature_detected) $($rest)+
532 )
533 };
534 (@__tgtfeat_dispatch_feat_chain_entry ("aarch64") ($($opts: meta),*) $($rest: tt)+) => {
535 $crate::target_feature_dispatch!(
536 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
537 (::std::arch::is_aarch64_feature_detected) $($rest)+
538 )
539 };
540 (@__tgtfeat_dispatch_feat_chain_entry ("arm64ec") ($($opts: meta),*) $($rest: tt)+) => {
541 $crate::target_feature_dispatch!(
542 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
543 (::std::arch::is_aarch64_feature_detected) $($rest)+
544 )
545 };
546 (@__tgtfeat_dispatch_feat_chain_entry (family("riscv")) ($($opts: meta),*) $($rest: tt)+) => {
548 $crate::target_feature_dispatch!(
549 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
550 (::std::arch::is_riscv_feature_detected) $($rest)+
551 )
552 };
553 (@__tgtfeat_dispatch_feat_chain_entry ("riscv32") ($($opts: meta),*) $($rest: tt)+) => {
554 $crate::target_feature_dispatch!(
555 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
556 (::std::arch::is_riscv_feature_detected) $($rest)+
557 )
558 };
559 (@__tgtfeat_dispatch_feat_chain_entry ("riscv64") ($($opts: meta),*) $($rest: tt)+) => {
560 $crate::target_feature_dispatch!(
561 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
562 (::std::arch::is_riscv_feature_detected) $($rest)+
563 )
564 };
565 (@__tgtfeat_dispatch_feat_chain_entry (family("x86")) ($($opts: meta),*) $($rest: tt)+) => {
567 $crate::target_feature_dispatch!(
568 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
569 (::std::arch::is_x86_feature_detected) $($rest)+
570 )
571 };
572 (@__tgtfeat_dispatch_feat_chain_entry ("x86") ($($opts: meta),*) $($rest: tt)+) => {
573 $crate::target_feature_dispatch!(
574 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
575 (::std::arch::is_x86_feature_detected) $($rest)+
576 )
577 };
578 (@__tgtfeat_dispatch_feat_chain_entry ("x86_64") ($($opts: meta),*) $($rest: tt)+) => {
579 $crate::target_feature_dispatch!(
580 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
581 (::std::arch::is_x86_feature_detected) $($rest)+
582 )
583 };
584 (@__tgtfeat_dispatch_feat_chain_entry ("arm") ($($opts: meta),*) $($rest: tt)+) => {
586 $crate::target_feature_dispatch!(
587 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
588 (::std::arch::is_arm_feature_detected) $($rest)+
589 )
590 };
591 (@__tgtfeat_dispatch_feat_chain_entry ("loongarch64") ($($opts: meta),*) $($rest: tt)+) => {
593 $crate::target_feature_dispatch!(
594 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
595 (::std::arch::is_loongarch_feature_detected) $($rest)+
596 )
597 };
598 (@__tgtfeat_dispatch_feat_chain_entry ("mips") ($($opts: meta),*) $($rest: tt)+) => {
600 $crate::target_feature_dispatch!(
601 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
602 (::std::arch::is_mips_feature_detected) $($rest)+
603 )
604 };
605 (@__tgtfeat_dispatch_feat_chain_entry ("mips64") ($($opts: meta),*) $($rest: tt)+) => {
607 $crate::target_feature_dispatch!(
608 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
609 (::std::arch::is_mips64_feature_detected) $($rest)+
610 )
611 };
612 (@__tgtfeat_dispatch_feat_chain_entry ("powerpc") ($($opts: meta),*) $($rest: tt)+) => {
614 $crate::target_feature_dispatch!(
615 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
616 (::std::arch::is_powerpc_feature_detected) $($rest)+
617 )
618 };
619 (@__tgtfeat_dispatch_feat_chain_entry ("powerpc64") ($($opts: meta),*) $($rest: tt)+) => {
621 $crate::target_feature_dispatch!(
622 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
623 (::std::arch::is_powerpc64_feature_detected) $($rest)+
624 )
625 };
626 (@__tgtfeat_dispatch_feat_chain_entry ("s390x") ($($opts: meta),*) $($rest: tt)+) => {
628 $crate::target_feature_dispatch!(
629 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
630 (::std::arch::is_s390x_feature_detected) $($rest)+
631 )
632 };
633 (@__tgtfeat_dispatch_feat_chain_entry (class("arm")) ($($opts: meta),*) $($rest: tt)+) => {
635 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
636 };
637 (@__tgtfeat_dispatch_feat_chain_entry (class("mips")) ($($opts: meta),*) $($rest: tt)+) => {
639 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
640 };
641 (@__tgtfeat_dispatch_feat_chain_entry (class("mips-classic")) ($($opts: meta),*) $($rest: tt)+) => {
643 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
644 };
645 (@__tgtfeat_dispatch_feat_chain_entry (class("powerpc")) ($($opts: meta),*) $($rest: tt)+) => {
647 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
648 };
649 (@__tgtfeat_dispatch_feat_chain_entry (class("sparc")) ($($opts: meta),*) $($rest: tt)+) => {
651 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
652 };
653 (@__tgtfeat_dispatch_feat_chain_entry (class("wasm")) ($($opts: meta),*) $($rest: tt)+) => {
655 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
656 };
657 (@__tgtfeat_dispatch_feat_chain_entry ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) $($rest: tt)+) => {
659 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
660 };
661
662 (
667 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($dyn: meta, $nightly: meta) ($detect: path)
668 ($($else_sta: tt)*) ($($else_dyn: tt)*) $($rest: tt)+
669 ) => {
670 {
671 #[cfg($dyn)]
672 {
673 $crate::target_feature_dispatch!(
674 @__tgtfeat_dispatch_feat_chain_dynamic
675 ($detect)
676 ($($else_sta)*) ($($else_dyn)*) $($rest)+
677 )
678 }
679 #[cfg(not($dyn))]
680 {
681 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_static ($($else_sta)*) $($rest)+)
682 }
683 }
684 };
685 (
687 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($dyn: meta, $nightly: meta) ($detect: path)
688 ($($else_sta: tt)*) ($($else_dyn: tt)*) $($rest: tt)+
689 ) => {
690 {
691 #[cfg(all($dyn, $nightly))]
692 {
693 $crate::target_feature_dispatch!(
694 @__tgtfeat_dispatch_feat_chain_dynamic
695 ($detect)
696 ($($else_sta)*) ($($else_dyn)*) $($rest)+
697 )
698 }
699 #[cfg(not(all($dyn, $nightly)))]
700 {
701 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_static ($($else_sta)*) $($rest)+)
702 }
703 }
704 };
705 (
707 @__tgtfeat_dispatch_feat_chain_dispatch_static ($dyn: meta, $nightly: meta)
708 ($($else_sta: tt)*) ($($else_dyn: tt)*) $($rest: tt)+
709 ) => {
710 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_static ($($else_sta)*) $($rest)+)
711 };
712
713 (
719 @__tgtfeat_dispatch_feat_chain_dynamic ($detect: path)
720 ($($else_sta: tt)*) (@__tgtfeat_dispatch_no_fallback) $((($($feat: tt)&&+) ($($if: tt)*)))+
721 ) => {
722 $(
723 if $({$detect!($feat)})&&+ {
724 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($if)*)
725 }
726 )else+
727 else {
728 $crate::target_feature_dispatch!(
729 @__tgtfeat_dispatch_feat_chain_static
730 ($($else_sta)*) $((($($feat)&&+) ($($if)*)))+
731 )
732 }
733 };
734 (
737 @__tgtfeat_dispatch_feat_chain_dynamic ($detect: path)
738 ($($else_sta: tt)*) ($($else_dyn: tt)*) $((($($feat: tt)&&+) ($($if: tt)*)))+
739 ) => {
740 $(
741 if $({$detect!($feat)})&&+ {
742 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($if)*)
743 }
744 )else+
745 else {
746 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($else_dyn)*)
747 }
748 };
749
750 (@__tgtfeat_dispatch_feat_chain_static ($($else: tt)*) (($($feat: tt)&&+) ($($if: tt)*)) $($rest: tt)*) => {
755 {
756 #[cfg(all($(target_feature = $feat),+))]
757 {
758 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($if)*)
759 }
760 #[cfg(not(all($(target_feature = $feat),+)))]
761 {
762 $crate::target_feature_dispatch!(
763 @__tgtfeat_dispatch_feat_chain_static
764 ($($else)*) $($rest)*
765 )
766 }
767 }
768 };
769 (@__tgtfeat_dispatch_feat_chain_static ($($else: tt)*)) => {
771 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($else)*)
772 };
773
774 (@__tgtfeat_dispatch_as_expr $expr: expr) => { $expr };
776 (@__tgtfeat_dispatch_as_expr) => { () };
778 (@__tgtfeat_dispatch_as_expr {$($tt: tt)+}) => {
781 compile_error!(concat!("failed to parse { ", stringify!($($tt)+), "} as expression"));
782 };
783 (@__tgtfeat_dispatch_as_expr $($tt: tt)+) => {
785 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr { $($tt)+ } )
786 };
787}