macerator/backend/x86/
mod.rs1#![allow(
2 clippy::missing_transmute_annotations,
3 clippy::useless_transmute,
4 clippy::transmute_int_to_float,
5 unused_unsafe
6)]
7#![cfg_attr(all(avx512, not(avx512_nightly)), allow(incompatible_msrv))]
9
10pub mod v2;
11pub mod v3;
12#[cfg(avx512)]
13pub mod v4;
14
15pub use v2::V2;
16pub use v3::V3;
17#[cfg(avx512)]
18pub use v4::V4;
19#[cfg(fp16)]
20pub use v4::V4FP16;
21
22macro_rules! lanes {
23 ($($bits: literal),*) => {
24 $(paste! {
25 #[inline(always)]
26 fn [<lanes $bits>]() -> usize {
27 WIDTH / $bits
28 }
29 })*
30 };
31}
32pub(crate) use lanes;
33
34macro_rules! impl_binop_scalar {
35 ($func: ident, $intrinsic: path, $($ty: ty),*) => {
36 $(paste! {
37 #[inline(always)]
38 fn [<$func _ $ty>](a: Self::Register, b: Self::Register) -> Self::Register {
39 const LANES: usize = WIDTH / (8 * size_of::<$ty>());
40 let a: [$ty; LANES] = cast!(a);
41 let b: [$ty; LANES] = cast!(b);
42 let mut out = [$ty::default(); LANES];
43
44 for i in 0..LANES {
45 out[i] = $intrinsic(a[i], b[i]);
46 }
47 cast!(out)
48 }
49 #[inline(always)]
50 fn [<$func _ $ty _supported>]() -> bool {
51 false
52 }
53 })*
54 };
55}
56pub(crate) use impl_binop_scalar;
57
58macro_rules! impl_unop_scalar {
59 ($func: ident, $intrinsic: path, $($ty: ty),*) => {
60 $(paste! {
61 #[inline(always)]
62 fn [<$func _ $ty>](a: Self::Register) -> Self::Register {
63 const LANES: usize = WIDTH / (8 * size_of::<$ty>());
64 let a: [$ty; LANES] = cast!(a);
65 let mut out = [$ty::default(); LANES];
66
67 for i in 0..LANES {
68 out[i] = a[i].$intrinsic();
69 }
70 cast!(out)
71 }
72 #[inline(always)]
73 fn [<$func _ $ty _supported>]() -> bool {
74 false
75 }
76 })*
77 };
78}
79pub(crate) use impl_unop_scalar;
80
81macro_rules! with_ty {
82 ($func: ident, f16) => {
83 paste!([<$func _ph>])
84 };
85 ($func: ident, f32) => {
86 paste!([<$func _ps>])
87 };
88 ($func: ident, f64) => {
89 paste!([<$func _pd>])
90 };
91 ($func: ident, $ty: ident) => {
92 paste!([<$func _ep $ty>])
93 }
94}
95pub(crate) use with_ty;
96
97macro_rules! with_ty_signless {
98 ($func: ident, u8) => {
99 with_ty!($func, i8)
100 };
101 ($func: ident, u16) => {
102 with_ty!($func, i16)
103 };
104 ($func: ident, u32) => {
105 with_ty!($func, i32)
106 };
107 ($func: ident, u64) => {
108 with_ty!($func, i64)
109 };
110 ($func: ident, $ty: ident) => {
111 with_ty!($func, $ty)
112 };
113}
114pub(crate) use with_ty_signless;
115
116macro_rules! impl_binop_signless {
117 ($func: ident, $intrinsic: ident, $($ty: ty),*) => {
118 $(paste! {
119 #[inline(always)]
120 fn [<$func _ $ty>](a: Self::Register, b: Self::Register) -> Self::Register {
121 cast!(with_ty_signless!($intrinsic, $ty)(cast!(a), cast!(b)))
122 }
123 #[inline(always)]
124 fn [<$func _ $ty _supported>]() -> bool {
125 true
126 }
127 })*
128 };
129}
130pub(crate) use impl_binop_signless;
131
132macro_rules! impl_binop {
133 ($func: ident, $intrinsic: ident, $($ty: ty),*) => {
134 $(paste! {
135 #[inline(always)]
136 fn [<$func _ $ty>](a: Self::Register, b: Self::Register) -> Self::Register {
137 cast!(with_ty!($intrinsic, $ty)(cast!(a), cast!(b)))
138 }
139 #[inline(always)]
140 fn [<$func _ $ty _supported>]() -> bool {
141 true
142 }
143 })*
144 };
145}
146pub(crate) use impl_binop;
147
148macro_rules! impl_binop_untyped {
149 ($func: ident, $intrinsic: ident) => {
150 paste! {
151 #[inline(always)]
152 fn $func(a: Self::Register, b: Self::Register) -> Self::Register {
153 cast!($intrinsic(cast!(a), cast!(b)))
154 }
155 #[inline(always)]
156 fn [<$func _supported>]() -> bool {
157 true
158 }
159 }
160 };
161}
162pub(crate) use impl_binop_untyped;
163
164macro_rules! impl_unop {
165 ($func: ident, $intrinsic: ident, $($ty: ty),*) => {
166 $(paste! {
167 #[inline(always)]
168 fn [<$func _ $ty>](a: Self::Register) -> Self::Register {
169 cast!(with_ty!($intrinsic, $ty)(cast!(a)))
170 }
171 #[inline(always)]
172 fn [<$func _ $ty _supported>]() -> bool {
173 true
174 }
175 })*
176 };
177}
178pub(crate) use impl_unop;
179
180macro_rules! impl_cmp {
181 ($func: ident, $intrinsic: ident, $($ty: ty),*) => {
182 $(paste! {
183 #[inline(always)]
184 fn [<$func _ $ty>](a: Self::Register, b: Self::Register) -> <$ty as Scalar>::Mask<Self> {
185 cast!(with_ty_signless!($intrinsic, $ty)(cast!(a), cast!(b)))
186 }
187 #[inline(always)]
188 fn [<$func _ $ty _supported>]() -> bool {
189 true
190 }
191 })*
192 };
193}
194pub(crate) use impl_cmp;