generic_simd/arch/
generic.rs1use crate::{
4 arch::Token,
5 scalar::Scalar,
6 shim::{Shim2, Shim4, Shim8},
7 vector::{width, Native, Vector},
8};
9
10#[cfg(feature = "complex")]
11use num_complex::Complex;
12
13#[derive(Copy, Clone, Debug)]
15pub struct Generic;
16
17unsafe impl Token for Generic {
18 #[inline]
19 fn new() -> Option<Self> {
20 Some(Self)
21 }
22
23 #[inline]
24 unsafe fn new_unchecked() -> Self {
25 Self
26 }
27}
28
29#[derive(Clone, Copy, Debug)]
31#[repr(transparent)]
32#[allow(non_camel_case_types)]
33pub struct f32x1(f32);
34
35#[derive(Clone, Copy, Debug)]
37#[repr(transparent)]
38#[allow(non_camel_case_types)]
39pub struct f64x1(f64);
40
41#[cfg(feature = "complex")]
45#[derive(Clone, Copy, Debug)]
46#[repr(transparent)]
47#[allow(non_camel_case_types)]
48pub struct cf32x1(Complex<f32>);
49
50#[cfg(feature = "complex")]
54#[derive(Clone, Copy, Debug)]
55#[repr(transparent)]
56#[allow(non_camel_case_types)]
57pub struct cf64x1(Complex<f64>);
58
59macro_rules! implement {
60 {
61 $vector:ty, $scalar:ty
62 } => {
63 impl Scalar<Generic, width::W1> for $scalar {
64 type Vector = $vector;
65 }
66
67 impl Scalar<Generic, width::W2> for $scalar {
68 type Vector = Shim2<$vector, $scalar>;
69 }
70
71 impl Scalar<Generic, width::W4> for $scalar {
72 type Vector = Shim4<$vector, $scalar>;
73 }
74
75 impl Scalar<Generic, width::W8> for $scalar {
76 type Vector = Shim8<$vector, $scalar>;
77 }
78
79 impl Native<Generic> for $scalar {
80 type Width = width::W1;
81 }
82 }
83}
84
85implement! { f32x1, f32 }
86implement! { f64x1, f64 }
87
88#[cfg(feature = "complex")]
89implement! { cf32x1, Complex<f32> }
90#[cfg(feature = "complex")]
91implement! { cf64x1, Complex<f64> }
92
93macro_rules! implement {
94 {
95 $vector:ty, $scalar:ty
96 } => {
97 arithmetic_ops! {
98 feature: Generic::new_unchecked(),
99 for $vector:
100 add -> (),
101 sub -> (),
102 mul -> (),
103 div -> ()
104 }
105
106 impl core::ops::Neg for $vector {
107 type Output = Self;
108
109 #[inline]
110 fn neg(self) -> Self {
111 Self(-self.0)
112 }
113 }
114
115 as_slice! { $vector }
116
117 unsafe impl Vector for $vector {
118 type Scalar = $scalar;
119
120 type Token = Generic;
121
122 type Width = crate::vector::width::W1;
123
124 type Underlying = $scalar;
125
126 #[inline]
127 fn zeroed(_: Self::Token) -> Self {
128 Self(<$scalar>::default())
129 }
130
131 #[inline]
132 fn splat(_: Self::Token, from: Self::Scalar) -> Self {
133 Self(from)
134 }
135 }
136 }
137}
138
139implement! { f32x1, f32 }
140implement! { f64x1, f64 }
141
142#[cfg(feature = "complex")]
143implement! { cf32x1, Complex<f32> }
144#[cfg(feature = "complex")]
145implement! { cf64x1, Complex<f64> }
146
147#[cfg(feature = "complex")]
148macro_rules! implement_complex {
149 {
150 $vector:ty, $real:ty
151 } => {
152 impl crate::vector::Complex for $vector {
153 type RealScalar = $real;
154
155 #[inline]
156 fn conj(self) -> Self {
157 Self(Complex::new(self.0.re, -self.0.im))
158 }
159
160 #[inline]
161 fn mul_i(self) -> Self {
162 Self(Complex::new(-self.0.im, self.0.re))
163 }
164
165 #[inline]
166 fn mul_neg_i(self) -> Self {
167 Self(Complex::new(self.0.im, -self.0.re))
168 }
169 }
170 }
171}
172
173#[cfg(feature = "complex")]
174implement_complex! { cf32x1, f32 }
175#[cfg(feature = "complex")]
176implement_complex! { cf64x1, f64 }