v_escape_base/arch/x86_64/
mod.rs1pub mod avx;
3
4pub mod sse;
6
7#[doc(hidden)]
15#[macro_export]
16macro_rules! ifun {
17 (
18 $name:ident,
19 $writer_builder:path,
20 $builder:ty,
21 $buffer:ty
22 $(,$retty:ty)?
23 ) => {
24 pub fn $name(haystack: &str, buffer: &mut $buffer) $(-> $retty)? {
25 use core::sync::atomic::{AtomicPtr, Ordering};
26
27 type Fn = *mut ();
28 type RealFn = fn(haystack: &str, buffer: &mut $buffer) $(-> $retty)?;
29 static FN: AtomicPtr<()> = AtomicPtr::new(detect as Fn);
30
31 #[cfg(target_feature = "sse2")]
32 #[target_feature(enable = "sse2", enable = "avx2")]
33 $writer_builder!(escape_avx2, $crate::arch::x86_64::avx::escape, escape, $builder);
34
35 #[cfg(target_feature = "sse2")]
36 #[target_feature(enable = "sse2")]
37 $writer_builder!(escape_sse2, $crate::arch::x86_64::sse::escape, escape, $builder);
38
39 $writer_builder!(escape_fallback, $crate::arch::fallback::escape_fallback, escape_fallback, $builder);
40
41 unsafe fn detect(haystack: &str, buffer: &mut $buffer) $(-> $retty)? {
42 let fun = {
43 #[cfg(not(target_feature = "sse2"))]
44 {
45 escape_fallback
46 }
47 #[cfg(target_feature = "sse2")]
48 {
49 if $crate::arch::x86_64::avx::is_available() {
50 escape_avx2
51 } else if $crate::arch::x86_64::sse::is_available() {
52 escape_sse2
53 } else {
54 escape_fallback
55 }
56 }
57 };
58 FN.store(fun as Fn, Ordering::Relaxed);
59 fun(haystack, buffer)
65 }
66
67 unsafe {
72 let fun = FN.load(Ordering::Relaxed);
73 core::mem::transmute::<Fn, RealFn>(fun)(
74 haystack,
75 buffer
76 )
77 }
78 }
79 };
80}
81
82#[macro_export]
87macro_rules! escape_builder {
88 ($builder:ty) => {
89 $crate::struct_display!(
90 escape_fmt,
91 escape_fmt_internal,
92 $crate::ifun!(
93 escape_fmt_internal,
94 $crate::builder_fmt,
95 $builder,
96 core::fmt::Formatter<'_>,
97 core::fmt::Result
98 ),
99 $builder
100 );
101
102 $crate::struct_string!($crate::ifun!(
103 escape_string,
104 $crate::builder_string,
105 $builder,
106 String
107 ));
108
109 $crate::struct_bytes!($crate::ifun!(
110 escape_bytes,
111 $crate::builder_bytes,
112 $builder,
113 Vec<u8>
114 ));
115 };
116}