62 static constexpr size_t n =
sizeof (vSIMDType) /
sizeof (
ScalarType);
63 static constexpr size_t mask = (
sizeof (vSIMDType) /
sizeof (
ScalarType)) - 1;
64 static constexpr size_t bits = SIMDInternal::Log2Helper<(
int) n>::value;
68 union UnionType { vSIMDType v;
ScalarType s[n]; };
69 union UnionMaskType { vSIMDType v; MaskType m[n]; };
73 static forcedinline vSIMDType add (vSIMDType
a, vSIMDType
b)
noexcept {
return apply<ScalarAdd> (
a,
b); }
74 static forcedinline vSIMDType sub (vSIMDType
a, vSIMDType
b)
noexcept {
return apply<ScalarSub> (
a,
b); }
75 static forcedinline vSIMDType mul (vSIMDType
a, vSIMDType
b)
noexcept {
return apply<ScalarMul> (
a,
b); }
76 static forcedinline vSIMDType bit_and (vSIMDType
a, vSIMDType
b)
noexcept {
return bitapply<ScalarAnd> (
a,
b); }
78 static forcedinline vSIMDType bit_xor (vSIMDType
a, vSIMDType
b)
noexcept {
return bitapply<ScalarXor> (
a,
b); }
79 static forcedinline vSIMDType bit_notand (vSIMDType
a, vSIMDType
b)
noexcept {
return bitapply<ScalarNot> (
a,
b); }
81 static forcedinline vSIMDType min (vSIMDType
a, vSIMDType
b)
noexcept {
return apply<ScalarMin> (
a,
b); }
82 static forcedinline vSIMDType max (vSIMDType
a, vSIMDType
b)
noexcept {
return apply<ScalarMax> (
a,
b); }
83 static forcedinline vSIMDType equal (vSIMDType
a, vSIMDType
b)
noexcept {
return cmp<ScalarEq > (
a,
b); }
84 static forcedinline vSIMDType notEqual (vSIMDType
a, vSIMDType
b)
noexcept {
return cmp<ScalarNeq> (
a,
b); }
85 static forcedinline vSIMDType greaterThan (vSIMDType
a, vSIMDType
b)
noexcept {
return cmp<ScalarGt > (
a,
b); }
86 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType
a, vSIMDType
b)
noexcept {
return cmp<ScalarGeq> (
a,
b); }
88 static forcedinline
ScalarType get (vSIMDType v,
size_t i)
noexcept
94 static forcedinline vSIMDType set (vSIMDType v,
size_t i,
ScalarType s)
noexcept
102 static forcedinline vSIMDType bit_not (vSIMDType
av)
noexcept
104 UnionMaskType
a {
av};
106 for (
size_t i = 0; i < n; ++i)
112 static forcedinline
ScalarType sum (vSIMDType
av)
noexcept
117 for (
size_t i = 0; i < n; ++i)
123 static forcedinline vSIMDType truncate (vSIMDType
av)
noexcept
127 for (
size_t i = 0; i < n; ++i)
130 a.s[i] =
static_cast <ScalarType> (
static_cast<int> (
a.s[i]));
136 static forcedinline vSIMDType multiplyAdd (vSIMDType
av, vSIMDType
bv, vSIMDType
cv)
noexcept
140 for (
size_t i = 0; i < n; ++i)
141 a.s[i] +=
b.s[i] *
c.s[i];
147 static forcedinline
bool allEqual (vSIMDType
av, vSIMDType
bv)
noexcept
151 for (
size_t i = 0; i < n; ++i)
152 if (
a.s[i] !=
b.s[i])
159 static forcedinline vSIMDType cmplxmul (vSIMDType
av, vSIMDType
bv)
noexcept
161 UnionType
a {
av},
b {
bv}, r;
163 const int m = n >> 1;
164 for (
int i = 0; i < m; ++i)
166 std::complex<ScalarType> result
167 = std::complex<ScalarType> (
a.s[i<<1],
a.s[(i<<1)|1])
168 * std::complex<ScalarType> (
b.s[i<<1],
b.s[(i<<1)|1]);
170 r.s[i<<1] = result.real();
171 r.s[(i<<1)|1] = result.imag();
182 struct ScalarAnd {
static forcedinline MaskType op (MaskType
a, MaskType
b)
noexcept {
return a &
b; } };
183 struct ScalarOr {
static forcedinline MaskType op (MaskType
a, MaskType
b)
noexcept {
return a |
b; } };
184 struct ScalarXor {
static forcedinline MaskType op (MaskType
a, MaskType
b)
noexcept {
return a ^
b; } };
185 struct ScalarNot {
static forcedinline MaskType op (MaskType
a, MaskType
b)
noexcept {
return (~
a) &
b; } };
192 template <
typename Op>
193 static forcedinline vSIMDType apply (vSIMDType
av, vSIMDType
bv)
noexcept
197 for (
size_t i = 0; i < n; ++i)
198 a.s[i] = Op::op (
a.s[i],
b.s[i]);
203 template <
typename Op>
204 static forcedinline vSIMDType cmp (vSIMDType
av, vSIMDType
bv)
noexcept
209 for (
size_t i = 0; i < n; ++i)
210 r.m[i] = Op::op (
a.s[i],
b.s[i]) ?
static_cast<MaskType
> (-1) :
static_cast<MaskType
> (0);
215 template <
typename Op>
216 static forcedinline vSIMDType bitapply (vSIMDType
av, vSIMDType
bv)
noexcept
218 UnionMaskType
a {
av},
b {
bv};
220 for (
size_t i = 0; i < n; ++i)
221 a.m[i] = Op::op (
a.m[i],
b.m[i]);
226 static forcedinline vSIMDType expand (
ScalarType s)
noexcept
230 for (
size_t i = 0; i < n; ++i)
236 static forcedinline vSIMDType load (
const ScalarType*
a)
noexcept
240 for (
size_t i = 0; i < n; ++i)
246 static forcedinline
void store (vSIMDType
av,
ScalarType* dest)
noexcept
250 for (
size_t i = 0; i < n; ++i)
254 template <
unsigned int shuffle_
idx>
255 static forcedinline vSIMDType shuffle (vSIMDType
av)
noexcept
261 for (
size_t i = 0; i < n; ++i)