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("mipsr6")) ($($if: tt)*)) $($rest: tt)*) => {
243 {
244 #[cfg(any(target_arch = "mips32r6", target_arch = "mips64r6"))]
245 {
246 $crate::target_feature_dispatch!(
247 @__tgtfeat_dispatch_arch_clause (class("mipsr6")) ($($opts),*)
248 ($($else)*) ($($if)*)
249 )
250 }
251 #[cfg(not(any(target_arch = "mips32r6", target_arch = "mips64r6")))]
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("powerpc")) ($($if: tt)*)) $($rest: tt)*) => {
262 {
263 #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
264 {
265 $crate::target_feature_dispatch!(
266 @__tgtfeat_dispatch_arch_clause (class("powerpc")) ($($opts),*)
267 ($($else)*) ($($if)*)
268 )
269 }
270 #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
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("sparc")) ($($if: tt)*)) $($rest: tt)*) => {
281 {
282 #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))]
283 {
284 $crate::target_feature_dispatch!(
285 @__tgtfeat_dispatch_arch_clause (class("sparc")) ($($opts),*)
286 ($($else)*) ($($if)*)
287 )
288 }
289 #[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))]
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)*) ((class("wasm")) ($($if: tt)*)) $($rest: tt)*) => {
300 {
301 #[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))]
302 {
303 $crate::target_feature_dispatch!(
304 @__tgtfeat_dispatch_arch_clause (class("wasm")) ($($opts),*)
305 ($($else)*) ($($if)*)
306 )
307 }
308 #[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
309 {
310 $crate::target_feature_dispatch!(
311 @__tgtfeat_dispatch_arch_chain ($($opts),*)
312 ($($else)*) $($rest)*
313 )
314 }
315 }
316 };
317 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*) (($($arch: tt $(($arch_arg: tt))?)||+) ($($if: tt)*)) $($rest: tt)*) => {
319 $crate::target_feature_dispatch!(
320 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
321 (() ($($arch$(($arch_arg))?)||+) ($($if)*)) $($rest)*
322 )
323 };
324 (@__tgtfeat_dispatch_arch_chain ($($opts: meta),*) ($($else: tt)*)) => {
326 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($else)*)
327 };
328
329 (
335 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
336 (($($added: tt,)*) (family("aarch64") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
337 ) => {
338 $crate::target_feature_dispatch!(
339 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
340 (($($added,)* "aarch64", "arm64ec",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
341 $($rest)*
342 )
343 };
344 (
346 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
347 (($($added: tt,)*) (family("riscv") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
348 ) => {
349 $crate::target_feature_dispatch!(
350 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
351 (($($added,)* "riscv32", "riscv64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
352 $($rest)*
353 )
354 };
355 (
357 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
358 (($($added: tt,)*) (family("x86") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
359 ) => {
360 $crate::target_feature_dispatch!(
361 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
362 (($($added,)* "x86", "x86_64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
363 $($rest)*
364 )
365 };
366 (
368 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
369 (($($added: tt,)*) (class("arm") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
370 ) => {
371 $crate::target_feature_dispatch!(
372 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
373 (($($added,)* "aarch64", "arm64ec", "arm",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
374 $($rest)*
375 )
376 };
377 (
379 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
380 (($($added: tt,)*) (class("mips") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
381 ) => {
382 $crate::target_feature_dispatch!(
383 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
384 (($($added,)* "mips", "mips64", "mips32r6", "mips64r6",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
385 $($rest)*
386 )
387 };
388 (
390 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
391 (($($added: tt,)*) (class("mips-classic") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
392 ) => {
393 $crate::target_feature_dispatch!(
394 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
395 (($($added,)* "mips", "mips64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
396 $($rest)*
397 )
398 };
399 (
401 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
402 (($($added: tt,)*) (class("mipsr6") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
403 ) => {
404 $crate::target_feature_dispatch!(
405 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
406 (($($added,)* "mips32r6", "mips64r6",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
407 $($rest)*
408 )
409 };
410 (
412 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
413 (($($added: tt,)*) (class("powerpc") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
414 ) => {
415 $crate::target_feature_dispatch!(
416 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
417 (($($added,)* "powerpc", "powerpc64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
418 $($rest)*
419 )
420 };
421 (
423 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
424 (($($added: tt,)*) (class("sparc") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
425 ) => {
426 $crate::target_feature_dispatch!(
427 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
428 (($($added,)* "sparc", "sparc64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
429 $($rest)*
430 )
431 };
432 (
434 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
435 (($($added: tt,)*) (class("wasm") $(|| $($arch2: tt $(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
436 ) => {
437 $crate::target_feature_dispatch!(
438 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
439 (($($added,)* "wasm32", "wasm64",) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
440 $($rest)*
441 )
442 };
443 (
445 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
446 (($($added: tt,)*) ($arch1: tt ($arch1_arg: tt) $(|| $($arch2: tt$(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
447 ) => {
448 compile_error!(concat!("Invalid architecture specifier: ", stringify!($arch1($arch1_arg))));
449 };
450 (
451 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
452 (($($added: tt,)*) ($arch1: tt $(|| $($arch2: tt$(($arch2_arg: tt))?)||+)?) ($($if: tt)*)) $($rest: tt)*
453 ) => {
454 $crate::target_feature_dispatch!(
455 @__tgtfeat_dispatch_arch_chain_2 ($($opts),*) ($($else)*)
456 (($($added,)* $arch1,) ($($($arch2$(($arch2_arg))?)||+)?) ($($if)*))
457 $($rest)*
458 )
459 };
460 (
462 @__tgtfeat_dispatch_arch_chain_2 ($($opts: meta),*) ($($else: tt)*)
463 (($($added: tt,)+) () ($($if: tt)*)) $($rest: tt)*
464 ) => {
465 {
466 #[cfg(any($(target_arch = $added),+))]
467 {
468 $crate::target_feature_dispatch!(
469 @__tgtfeat_dispatch_arch_clause ($($added)||+) ($($opts),*)
470 ($($else)*) ($($if)*)
471 )
472 }
473 #[cfg(not(any($(target_arch = $added),+)))]
474 {
475 $crate::target_feature_dispatch!(
476 @__tgtfeat_dispatch_arch_chain ($($opts),*)
477 ($($else)*) $($rest)*
478 )
479 }
480 }
481 };
482
483 (
503 @__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*)
504 ($(if $($feat: tt)&&+ { $($if: tt)* })else+)
505 ) => {
506 $crate::target_feature_dispatch!(
507 @__tgtfeat_dispatch_feat_chain_entry
508 ($($arch$(($arch_arg))?)||+) ($($opts),*)
509 ($($else1)*) (@__tgtfeat_dispatch_no_fallback)
510 $((($($feat)&&+) ($($if)*)))+
511 )
512 };
513 (
515 @__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*)
516 ($(if $($feat: tt)&&+ { $($if: tt)* })else+ else { @__tgtfeat_dispatch_no_fallback })
517 ) => {
518 compile_error!("invalid feature-specific `else` clause");
519 };
520 (
522 @__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*)
523 ($(if $($feat: tt)&&+ { $($if: tt)* })else+ else { $($else2: tt)* })
524 ) => {
525 $crate::target_feature_dispatch!(
526 @__tgtfeat_dispatch_feat_chain_entry
527 ($($arch$(($arch_arg))?)||+) ($($opts),*)
528 ($($else2)*) ($($else2)*)
529 $((($($feat)&&+) ($($if)*)))+
530 )
531 };
532 (@__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*) (($expr: expr))) => {
534 $expr
535 };
536 (@__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*) ({$($tt: tt)*})) => {
538 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($tt)*)
539 };
540 (@__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*) ()) => {
542 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr ())
543 };
544 (@__tgtfeat_dispatch_arch_clause ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) ($($else1: tt)*) ($($tt: tt)*)) => {
546 compile_error!("unsupported or invalid architecture clause");
547 };
548
549 (@__tgtfeat_dispatch_feat_chain_entry (family("aarch64")) ($($opts: meta),*) $($rest: tt)+) => {
559 $crate::target_feature_dispatch!(
560 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
561 (::std::arch::is_aarch64_feature_detected) $($rest)+
562 )
563 };
564 (@__tgtfeat_dispatch_feat_chain_entry ("aarch64") ($($opts: meta),*) $($rest: tt)+) => {
565 $crate::target_feature_dispatch!(
566 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
567 (::std::arch::is_aarch64_feature_detected) $($rest)+
568 )
569 };
570 (@__tgtfeat_dispatch_feat_chain_entry ("arm64ec") ($($opts: meta),*) $($rest: tt)+) => {
571 $crate::target_feature_dispatch!(
572 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
573 (::std::arch::is_aarch64_feature_detected) $($rest)+
574 )
575 };
576 (@__tgtfeat_dispatch_feat_chain_entry (family("riscv")) ($($opts: meta),*) $($rest: tt)+) => {
578 $crate::target_feature_dispatch!(
579 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
580 (::std::arch::is_riscv_feature_detected) $($rest)+
581 )
582 };
583 (@__tgtfeat_dispatch_feat_chain_entry ("riscv32") ($($opts: meta),*) $($rest: tt)+) => {
584 $crate::target_feature_dispatch!(
585 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
586 (::std::arch::is_riscv_feature_detected) $($rest)+
587 )
588 };
589 (@__tgtfeat_dispatch_feat_chain_entry ("riscv64") ($($opts: meta),*) $($rest: tt)+) => {
590 $crate::target_feature_dispatch!(
591 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
592 (::std::arch::is_riscv_feature_detected) $($rest)+
593 )
594 };
595 (@__tgtfeat_dispatch_feat_chain_entry (family("x86")) ($($opts: meta),*) $($rest: tt)+) => {
597 $crate::target_feature_dispatch!(
598 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
599 (::std::arch::is_x86_feature_detected) $($rest)+
600 )
601 };
602 (@__tgtfeat_dispatch_feat_chain_entry ("x86") ($($opts: meta),*) $($rest: tt)+) => {
603 $crate::target_feature_dispatch!(
604 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
605 (::std::arch::is_x86_feature_detected) $($rest)+
606 )
607 };
608 (@__tgtfeat_dispatch_feat_chain_entry ("x86_64") ($($opts: meta),*) $($rest: tt)+) => {
609 $crate::target_feature_dispatch!(
610 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($($opts),*)
611 (::std::arch::is_x86_feature_detected) $($rest)+
612 )
613 };
614 (@__tgtfeat_dispatch_feat_chain_entry ("arm") ($($opts: meta),*) $($rest: tt)+) => {
616 $crate::target_feature_dispatch!(
617 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
618 (::std::arch::is_arm_feature_detected) $($rest)+
619 )
620 };
621 (@__tgtfeat_dispatch_feat_chain_entry ("loongarch64") ($($opts: meta),*) $($rest: tt)+) => {
623 $crate::target_feature_dispatch!(
624 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
625 (::std::arch::is_loongarch_feature_detected) $($rest)+
626 )
627 };
628 (@__tgtfeat_dispatch_feat_chain_entry ("mips") ($($opts: meta),*) $($rest: tt)+) => {
630 $crate::target_feature_dispatch!(
631 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
632 (::std::arch::is_mips_feature_detected) $($rest)+
633 )
634 };
635 (@__tgtfeat_dispatch_feat_chain_entry ("mips64") ($($opts: meta),*) $($rest: tt)+) => {
637 $crate::target_feature_dispatch!(
638 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
639 (::std::arch::is_mips64_feature_detected) $($rest)+
640 )
641 };
642 (@__tgtfeat_dispatch_feat_chain_entry ("powerpc") ($($opts: meta),*) $($rest: tt)+) => {
644 $crate::target_feature_dispatch!(
645 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
646 (::std::arch::is_powerpc_feature_detected) $($rest)+
647 )
648 };
649 (@__tgtfeat_dispatch_feat_chain_entry ("powerpc64") ($($opts: meta),*) $($rest: tt)+) => {
651 $crate::target_feature_dispatch!(
652 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
653 (::std::arch::is_powerpc64_feature_detected) $($rest)+
654 )
655 };
656 (@__tgtfeat_dispatch_feat_chain_entry ("s390x") ($($opts: meta),*) $($rest: tt)+) => {
658 $crate::target_feature_dispatch!(
659 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($($opts),*)
660 (::std::arch::is_s390x_feature_detected) $($rest)+
661 )
662 };
663 (@__tgtfeat_dispatch_feat_chain_entry (class("arm")) ($($opts: meta),*) $($rest: tt)+) => {
665 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
666 };
667 (@__tgtfeat_dispatch_feat_chain_entry (class("mips")) ($($opts: meta),*) $($rest: tt)+) => {
669 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
670 };
671 (@__tgtfeat_dispatch_feat_chain_entry (class("mips-classic")) ($($opts: meta),*) $($rest: tt)+) => {
673 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
674 };
675 (@__tgtfeat_dispatch_feat_chain_entry (class("mipsr6")) ($($opts: meta),*) $($rest: tt)+) => {
677 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
678 };
679 (@__tgtfeat_dispatch_feat_chain_entry (class("powerpc")) ($($opts: meta),*) $($rest: tt)+) => {
681 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
682 };
683 (@__tgtfeat_dispatch_feat_chain_entry (class("sparc")) ($($opts: meta),*) $($rest: tt)+) => {
685 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
686 };
687 (@__tgtfeat_dispatch_feat_chain_entry (class("wasm")) ($($opts: meta),*) $($rest: tt)+) => {
689 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
690 };
691 (@__tgtfeat_dispatch_feat_chain_entry ($($arch: tt $(($arch_arg: tt))?)||+) ($($opts: meta),*) $($rest: tt)+) => {
693 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_dispatch_static ($($opts),*) $($rest)+)
694 };
695
696 (
701 @__tgtfeat_dispatch_feat_chain_dispatch_dyn ($dyn: meta, $nightly: meta) ($detect: path)
702 ($($else_sta: tt)*) ($($else_dyn: tt)*) $($rest: tt)+
703 ) => {
704 {
705 #[cfg($dyn)]
706 {
707 $crate::target_feature_dispatch!(
708 @__tgtfeat_dispatch_feat_chain_dynamic
709 ($detect)
710 ($($else_sta)*) ($($else_dyn)*) $($rest)+
711 )
712 }
713 #[cfg(not($dyn))]
714 {
715 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_static ($($else_sta)*) $($rest)+)
716 }
717 }
718 };
719 (
721 @__tgtfeat_dispatch_feat_chain_dispatch_dyn_nightly ($dyn: meta, $nightly: meta) ($detect: path)
722 ($($else_sta: tt)*) ($($else_dyn: tt)*) $($rest: tt)+
723 ) => {
724 {
725 #[cfg(all($dyn, $nightly))]
726 {
727 $crate::target_feature_dispatch!(
728 @__tgtfeat_dispatch_feat_chain_dynamic
729 ($detect)
730 ($($else_sta)*) ($($else_dyn)*) $($rest)+
731 )
732 }
733 #[cfg(not(all($dyn, $nightly)))]
734 {
735 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_static ($($else_sta)*) $($rest)+)
736 }
737 }
738 };
739 (
741 @__tgtfeat_dispatch_feat_chain_dispatch_static ($dyn: meta, $nightly: meta)
742 ($($else_sta: tt)*) ($($else_dyn: tt)*) $($rest: tt)+
743 ) => {
744 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_feat_chain_static ($($else_sta)*) $($rest)+)
745 };
746
747 (
753 @__tgtfeat_dispatch_feat_chain_dynamic ($detect: path)
754 ($($else_sta: tt)*) (@__tgtfeat_dispatch_no_fallback) $((($($feat: tt)&&+) ($($if: tt)*)))+
755 ) => {
756 $(
757 if $({$detect!($feat)})&&+ {
758 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($if)*)
759 }
760 )else+
761 else {
762 $crate::target_feature_dispatch!(
763 @__tgtfeat_dispatch_feat_chain_static
764 ($($else_sta)*) $((($($feat)&&+) ($($if)*)))+
765 )
766 }
767 };
768 (
771 @__tgtfeat_dispatch_feat_chain_dynamic ($detect: path)
772 ($($else_sta: tt)*) ($($else_dyn: tt)*) $((($($feat: tt)&&+) ($($if: tt)*)))+
773 ) => {
774 $(
775 if $({$detect!($feat)})&&+ {
776 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($if)*)
777 }
778 )else+
779 else {
780 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($else_dyn)*)
781 }
782 };
783
784 (@__tgtfeat_dispatch_feat_chain_static ($($else: tt)*) (($($feat: tt)&&+) ($($if: tt)*)) $($rest: tt)*) => {
789 {
790 #[cfg(all($(target_feature = $feat),+))]
791 {
792 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($if)*)
793 }
794 #[cfg(not(all($(target_feature = $feat),+)))]
795 {
796 $crate::target_feature_dispatch!(
797 @__tgtfeat_dispatch_feat_chain_static
798 ($($else)*) $($rest)*
799 )
800 }
801 }
802 };
803 (@__tgtfeat_dispatch_feat_chain_static ($($else: tt)*)) => {
805 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr $($else)*)
806 };
807
808 (@__tgtfeat_dispatch_as_expr $expr: expr) => { $expr };
810 (@__tgtfeat_dispatch_as_expr) => { () };
812 (@__tgtfeat_dispatch_as_expr {$($tt: tt)+}) => {
815 compile_error!(concat!("failed to parse { ", stringify!($($tt)+), "} as expression"));
816 };
817 (@__tgtfeat_dispatch_as_expr $($tt: tt)+) => {
819 $crate::target_feature_dispatch!(@__tgtfeat_dispatch_as_expr { $($tt)+ } )
820 };
821}