10#include "arm_simd/helpers.hpp"
11#include "arm_simd/helpers/multivector.hpp"
12#include "arm_simd/helpers/scalar.hpp"
13#include "arm_simd/helpers/vec64.hpp"
16#include "helpers/bool.hpp"
20#ifdef __ARM_FEATURE_MVE
26#ifdef ARGON_PLATFORM_SIMDE
27#define ace [[gnu::always_inline]] inline
29#define ace [[gnu::always_inline]] constexpr
31#define ace [[gnu::always_inline]] inline
42template <
typename T,
typename... Ts>
43inline constexpr bool is_one_of = std::disjunction_v<std::is_same<T, Ts>...>;
49template <
typename VectorType>
52 template <
size_t LaneIndex>
62 static constexpr size_t lanes = (simd::is_quadword_v<VectorType> ? 16 : 8) /
sizeof(
scalar_type);
74 ace
Vector(VectorType vector) : vec_{
std::move(vector)} {};
81#ifndef ARGON_PLATFORM_MVE
91 template <
size_t LaneIndex>
95 template <
typename... ArgTypes>
96 requires(
sizeof...(ArgTypes) > 1)
97 ace
Vector(ArgTypes... args) : vec_{
std::forward<ArgTypes>(args)...} {}
111#ifdef ARGON_PLATFORM_MVE
112 return simd::duplicate(scalar);
114 return simd::duplicate<VectorType>(scalar);
122 template <simd::is_vector_type IntrinsicType>
124#ifdef ARGON_PLATFORM_MVE
125 return simd::duplicate(lane.
Get());
127 return simd::duplicate_lane<vector_type>(lane.
vec(), lane.
lane());
135 template <
size_t LaneIndex>
137#ifdef ARGON_PLATFORM_MVE
138 return simd::duplicate(lane.
Get());
140 if constexpr (simd::is_quadword_v<VectorType>) {
142 return simd::duplicate_lane_quad<LaneIndex>(lane.
vec());
146 constexpr size_t local_lane = LaneIndex >= (
lanes / 2) ? LaneIndex - (
lanes / 2) : LaneIndex;
147 return simd::duplicate_lane_quad<local_lane>(lane.
vec());
150 return simd::duplicate_lane<LaneIndex>(lane.
vec());
163#if __cpp_if_consteval >= 202106L
164 return IotaHelper(start, std::make_index_sequence<lanes>{});
166 return Argon{start}.
Add(VectorType{0, 1, 2, 3});
174 template <
typename FuncType>
175 requires std::convertible_to<FuncType, std::function<
scalar_type()>>
179 std::array<scalar_type, lanes> out;
180 utility::constexpr_for<0, lanes, 1>([&]<
size_t i>() {
183 return Load(out.data());
191 template <
typename FuncType>
196 std::array<scalar_type, lanes> out;
197 utility::constexpr_for<0, lanes, 1>([&]<
size_t i>() {
200 return Load(out.data());
262#if ARGON_USE_COMPILER_EXTENSIONS
271#if ARGON_USE_COMPILER_EXTENSIONS
279 [[gnu::always_inline]]
constexpr VectorType
vec()
const {
return vec_; }
282 [[gnu::always_inline]]
constexpr operator VectorType()
const {
return vec_; }
287 std::array<scalar_type, lanes> out;
288 simd::store1(out.data(), vec_);
297#ifdef ARGON_PLATFORM_MVE
300 return {vec_,
static_cast<int>(i)};
304#ifdef ARGON_PLATFORM_MVE
307 return {vec_,
static_cast<int>(i)};
315#ifdef ARGON_PLATFORM_MVE
323#ifdef ARGON_PLATFORM_MVE
333 template <
size_t LaneIndex>
335#ifdef ARGON_PLATFORM_MVE
336 return vec_[LaneIndex];
342 template <
size_t LaneIndex>
344#ifdef ARGON_PLATFORM_MVE
345 return vec_[LaneIndex];
362 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
365 return simd::negate(vec_);
371 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
372 return vec_ + b.vec_;
374 return simd::add(vec_, b);
393 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
394 return vec_ - b.vec_;
396 return simd::subtract(vec_, b);
414#ifdef ARGON_PLATFORM_MVE
415 return mve::add(vec_, mve::subtract_absolute(b, c));
417 return neon::subtract_absolute_add(vec_, b, c);
423 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
424 return vec_ * b.vec_;
426 return simd::multiply(vec_, b);
432 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
435 return simd::multiply(vec_, b);
439#ifndef ARGON_PLATFORM_MVE
444 template <
size_t LaneIndex>
446 return neon::multiply_lane(vec_, b.
vec(), b.
lane());
453 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
454 return vec_ + b.vec_ * c.vec_;
456 return simd::multiply_add(vec_, b, c);
463 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
464 return vec_ + b.vec_ * c;
466 return simd::multiply_add(vec_, b, c);
474#ifndef ARGON_PLATFORM_MVE
478 return simd::multiply_add_lane(vec_, b.vec(), c.
vec(), c.
lane());
487 template <
size_t LaneIndex>
489 return simd::multiply_add_lane(vec_, b.vec(), c.
vec(), c.
lane());
493 template <
size_t LaneIndex>
502#if ARGON_USE_COMPILER_EXTENSIONS
503 return vec_ - b.vec_ * c.vec_;
505 return simd::multiply_subtract(vec_, b, c);
512#if ARGON_USE_COMPILER_EXTENSIONS
513 return vec_ - b.vec_ * c;
515 return simd::multiply_subtract(vec_, b, c);
523#ifndef ARGON_PLATFORM_MVE
527 return simd::multiply_subtract_lane(vec_, b.vec(), c.
vec(), c.
lane());
539#ifndef ARGON_PLATFORM_MVE
543 return simd::multiply_double_saturate_high_lane(vec_, l.
vec(), l.
lane());
550 return simd::multiply_double_round_saturate_high(vec_, v);
556 return simd::multiply_double_round_saturate_high(vec_, s);
559#ifndef ARGON_PLATFORM_MVE
563 return simd::multiply_double_round_saturate_high_lane(vec_, l.
vec(), l.
lane());
575#ifdef ARGON_PLATFORM_MVE
576 if constexpr (std::is_same_v<scalar_type, uint32_t>) {
577 std::numeric_limits<uint32_t>::max() / vec_;
582 return simd::reciprocal_estimate(vec_);
591#ifdef ARGON_PLATFORM_MVE
592 if constexpr (std::is_same_v<scalar_type, uint32_t>) {
593 return std::numeric_limits<uint32_t>::max() / (vec_ * vec_);
595 return 1.f / (vec_ * vec_);
598 return simd::reciprocal_sqrt_estimate(vec_);
606 requires std::floating_point<scalar_type>
608#ifdef ARGON_PLATFORM_MVE
609 return 2.f - vec_ * b.vec_;
611 return simd::reciprocal_step(vec_, b.vec_);
619 requires std::floating_point<scalar_type>
621#ifdef ARGON_PLATFORM_MVE
622 return (3.f - vec_ * b.vec_) * 0.5f;
624 return simd::reciprocal_sqrt_step(vec_, b.vec_);
635 for (
int i = 0; i < n_iters; ++i) {
648 for (
int i = 0; i < n_iters; ++i) {
656 template <
typename arg_type>
657 requires(is_one_of<arg_type, argon_type, scalar_type, lane_type> || std::is_convertible_v<arg_type, argon_type> ||
658 std::is_convertible_v<arg_type, scalar_type>)
660 return Add(b.MultiplyFixedQMax(c));
665 template <
typename arg_type>
666 requires(is_one_of<arg_type, argon_type, scalar_type, lane_type> || std::is_convertible_v<arg_type, argon_type> ||
667 std::is_convertible_v<arg_type, scalar_type>)
669 return Add(b.MultiplyRoundFixedQMax(c));
675 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
676 return vec_ / b.vec_;
678 return simd::divide(vec_, b);
684 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
685 return vec_ / b.vec_;
695 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
696 return vec_ % b.vec_;
697 }
else if constexpr (std::floating_point<scalar_type>) {
707 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
710 return this->map([b](
scalar_type lane1) {
return std::fmod(lane1, b); });
717 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
718 return vec_ > b.vec_ ? vec_ : b.vec_;
720 return simd::max(vec_, b);
726 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
727 return vec_ < b.vec_ ? vec_ : b.vec_;
729 return simd::min(vec_, b);
756 requires std::is_integral_v<scalar_type>
758 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
759 return vec_ << b.vec_;
761 return simd::shift_left(vec_, b.vec_);
768 requires std::is_integral_v<scalar_type>
770 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
774 return simd::shift_left(vec_, b.vec_);
782 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
785 return simd::shift_left<n>(vec_);
791 requires(std::is_integral_v<scalar_type>)
793 return simd::shift_left_saturate(vec_, b);
805 return simd::shift_left_saturate<n>(vec_);
815 return simd::shift_left_insert<n>(vec_, b);
821 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
824 return simd::shift_right<n>(vec_);
831 return simd::shift_right_round<n>(vec_);
839#ifdef ARGON_PLATFORM_MVE
840 return vec_ + (b >> n);
842 return simd::shift_right_accumulate<n>(vec_, b);
851#ifdef ARGON_PLATFORM_MVE
852 return vec_ + mve::shift_right_round<n>(b);
854 return simd::shift_right_accumulate_round<n>(vec_, b);
863 return simd::shift_right_insert<n>(vec_, b);
868#ifdef ARGON_PLATFORM_MVE
869 return mve::load1(ptr);
871 return neon::load1<VectorType>(ptr);
877#ifdef ARGON_PLATFORM_MVE
880 utility::constexpr_for<0, lanes, 1>([val, &
vec]<
int i>() {
vec[i] = val; });
882 return simd::load1_duplicate<VectorType>(ptr);
894#ifdef ARGON_PLATFORM_MVE
897 "Unsupported size for gather load");
900 return mve::load_byte_gather_offset(base, offset_vector);
902 return mve::load_halfword_gather_offset(base, offset_vector);
904 return mve::load_word_gather_offset(base, offset_vector);
906 return mve::load_doubleword_gather_offset(base, offset_vector);
910 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
911 auto lane_val = neon::get_lane<i>(offset_vector);
914 auto* addr =
reinterpret_cast<const scalar_type*
>(
reinterpret_cast<const char*
>(base) + lane_val);
929#ifdef ARGON_PLATFORM_MVE
932 "Unsupported size for gather load");
935 return mve::load_byte_gather_offset(base, offset_vector);
937 return mve::load_halfword_gather_offset(base, offset_vector *
sizeof(
scalar_type));
939 return mve::load_word_gather_offset(base, offset_vector *
sizeof(
scalar_type));
941 return mve::load_doubleword_gather_offset(base, offset_vector *
sizeof(
scalar_type));
945 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
946 auto lane_val = neon::get_lane<i>(offset_vector);
947 destination = destination.template
LoadToLane<i>(base + lane_val);
956 template <
size_t lane>
967 template <
size_t str
ide>
969#ifdef ARGON_PLATFORM_MVE
970 static_assert(stride == 2 || stride == 4,
971 "De-interleaving Loads can only be performed with a stride of 2, 3, or 4");
972 if constexpr (stride == 2) {
974 }
else if constexpr (stride == 4) {
978 static_assert(stride > 1 && stride < 5,
"De-interleaving Loads can only be performed with a stride of 2, 3, or 4");
979 using multivec_type = simd::MultiVector_t<VectorType, stride>;
980 if constexpr (stride == 2) {
982 }
else if constexpr (stride == 3) {
984 }
else if constexpr (stride == 4) {
995 template <
size_t str
ide>
997#ifdef ARGON_PLATFORM_MVE
998 static_assert(stride == 2 || stride == 4,
999 "De-interleaving LoadCopy can only be performed with a stride of 2, 3, or 4");
1000 if constexpr (stride == 2) {
1001 return {mve::duplicate(*ptr++), mve::duplicate(*ptr++)};
1002 }
else if constexpr (stride == 4) {
1003 return {mve::duplicate(*ptr++), mve::duplicate(*ptr++), mve::duplicate(*ptr++), mve::duplicate(*ptr)};
1006 static_assert(stride > 1 && stride < 5,
1007 "De-interleaving LoadCopy can only be performed with a stride of 2, 3, or 4");
1008 using multivec_type = simd::MultiVector<VectorType, stride>::type;
1009 if constexpr (stride == 2) {
1010 return argon::to_array(simd::load2_duplicate<multivec_type>(ptr).val);
1011 }
else if constexpr (stride == 3) {
1012 return argon::to_array(simd::load3_duplicate<multivec_type>(ptr).val);
1013 }
else if constexpr (stride == 4) {
1014 return argon::to_array(simd::load4_duplicate<multivec_type>(ptr).val);
1025 template <
size_t LaneIndex,
size_t Str
ide>
1028 static_assert(Stride > 1 && Stride < 5,
"De-interleaving Loads can only be performed with a stride of 2, 3, or 4");
1029#ifdef ARGON_PLATFORM_MVE
1031 utility::constexpr_for<0, Stride, 1>([&]<
int i>() {
1032 out.val[i][LaneIndex] = ptr[i];
1036 if constexpr (Stride == 2) {
1037 if constexpr (simd::is_quadword_v<VectorType>) {
1038 return argon::to_array(simd::load2_lane_quad<LaneIndex>(ptr, multi).val);
1042 }
else if constexpr (Stride == 3) {
1043 if constexpr (simd::is_quadword_v<VectorType>) {
1044 return argon::to_array(simd::load3_lane_quad<LaneIndex>(ptr, multi).val);
1048 }
else if constexpr (Stride == 4) {
1049 if constexpr (simd::is_quadword_v<VectorType>) {
1050 return argon::to_array(simd::load4_lane_quad<LaneIndex>(ptr, multi).val);
1059 template <
size_t lane,
size_t str
ide>
1062 using multivec_type = simd::MultiVector_t<VectorType, stride>;
1076 template <
size_t str
ide>
1080 static_assert(stride > 1 && stride < 5,
"De-interleaving Loads can only be performed with a stride of 2, 3, or 4");
1081 std::array<argon_type, stride> multi{};
1082 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1083 auto lane_val = simd::get_lane<i>(offset_vector);
1098 static_assert(n > 1 && n < 5,
"LoadMulti can only be performed with a size of 2, 3, or 4");
1099#ifdef ARGON_PLATFORM_MVE
1100 std::array<argon_type, n> multi{};
1101 utility::constexpr_for<0, n, 1>([&]<
int i>() {
1107#if defined(__clang__) || (__GNUC__ > 13)
1108 using multi_type = simd::MultiVector_t<VectorType, n>;
1109 if constexpr (n == 2) {
1111 }
else if constexpr (n == 3) {
1113 }
else if constexpr (n == 4) {
1119 if constexpr (n == 2) {
1120 auto a = simd::load1<VectorType>(ptr);
1121 auto b = simd::load1<VectorType>(ptr +
lanes);
1123 }
else if constexpr (n == 3) {
1124 auto a = simd::load1<VectorType>(ptr);
1125 auto b = simd::load1<VectorType>(ptr +
lanes);
1126 auto c = simd::load1<VectorType>(ptr + 2 *
lanes);
1128 }
else if constexpr (n == 4) {
1129 auto a = simd::load1<VectorType>(ptr);
1130 auto b = simd::load1<VectorType>(ptr +
lanes);
1131 auto c = simd::load1<VectorType>(ptr + 2 *
lanes);
1132 auto d = simd::load1<VectorType>(ptr + 3 *
lanes);
1133 return {a, b, c, d};
1146 template <
int LaneIndex>
1148#ifdef ARGON_PLATFORM_MVE
1149 *ptr = vec_[LaneIndex];
1151 simd::store1_lane<LaneIndex>(ptr, vec_);
1155#ifndef ARGON_PLATFORM_MVE
1178 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
1181 return simd::bitwise_not(vec_);
1187 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
1188 return vec_ & b.vec_;
1190 return simd::bitwise_and(vec_, b);
1196 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
1197 return vec_ | b.vec_;
1199 return simd::bitwise_or(vec_, b);
1205 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
1206 return vec_ ^ b.vec_;
1208 return simd::bitwise_xor(vec_, b);
1215 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
1216 return vec_ | ~b.vec_;
1218 return simd::bitwise_or_not(vec_, b);
1225 if constexpr (ARGON_USE_COMPILER_EXTENSIONS) {
1226 return vec_ & ~b.vec_;
1228 return simd::bitwise_clear(vec_, b);
1235#ifndef ARGON_PLATFORM_MVE
1238 template <
typename ArgType>
1239 requires std::is_unsigned_v<scalar_type>
1241 return simd::bitwise_select(vec_, true_value, false_value);
1245 template <
typename ArgType>
1246 requires std::is_unsigned_v<scalar_type>
1248 return simd::bitwise_select(true_value, false_value);
1264 return simd::count_leading_sign_bits(vec_);
1274#ifdef ARGON_PLATFORM_MVE
1275 auto new_vec = vec_;
1276 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1277 new_vec[i] = std::popcount(vec_[i]);
1281 return neon::count_active_bits(vec_);
1293#ifdef ARGON_PLATFORM_MVE
1294 auto new_vec = vec_;
1295 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1297 new_vec[i] = b.vec_[i];
1302 return simd::extract<n>(vec_, b);
1306 ace
argon_type Reverse64bit()
const {
return simd::reverse_64bit(vec_); }
1307 ace
argon_type Reverse32bit()
const {
return simd::reverse_32bit(vec_); }
1308 ace
argon_type Reverse16bit()
const {
return simd::reverse_16bit(vec_); }
1314#ifdef ARGON_PLATFORM_MVE
1315 std::array<argon_type, 2> new_vec;
1316 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1318 new_vec[0][i] = vec_[i / 2];
1319 new_vec[1][i] = vec_[(i +
lanes) / 2];
1321 new_vec[0][i] = b.vec_[i / 2];
1322 new_vec[1][i] = b.vec_[(i +
lanes) / 2];
1335#ifdef ARGON_PLATFORM_MVE
1336 std::array<argon_type, 2> new_vec;
1337 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1338 if ((i * 2) <
lanes) {
1339 new_vec[0][i] = vec_[i * 2];
1340 new_vec[1][i] = vec_[i * 2 + 1];
1342 new_vec[0][i] = b.vec_[i * 2];
1343 new_vec[1][i] = b.vec_[i * 2 + 1];
1358#ifdef ARGON_PLATFORM_MVE
1359 std::array<argon_type, 2> new_vec;
1360 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1362 new_vec[0][i] = vec_[i];
1363 new_vec[1][i] = vec_[i + 1];
1365 new_vec[0][i] = b.vec_[i + 1];
1366 new_vec[1][i] = b.vec_[i];
1378 template <
typename FuncType>
1382 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1383 out[i] = body(vec_[i]);
1388 template <
typename FuncType>
1390 ace
argon_type map_with_index(FuncType body)
const {
1392 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1393 out[i] = body(vec_[i], i);
1398 template <
typename FuncType>
1402 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1403 out[i] = body(vec_[i], other.vec_[i]);
1408 template <
typename FuncType>
1409 requires std::convertible_to<FuncType, std::function<void(
scalar_type&)>>
1411 VectorType out = vec_;
1412 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1423 template <
typename FuncType>
1424 requires std::convertible_to<FuncType, std::function<void(
scalar_type&,
int)>>
1425 ace
argon_type each_lane_with_index(FuncType body) {
1426 VectorType out = vec_;
1427 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1436 template <
typename FuncType>
1437 requires std::convertible_to<FuncType, std::function<void()>>
1438 ace
void if_lane(FuncType true_branch) {
1439 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1446 template <
typename FuncType>
1447 requires std::convertible_to<FuncType, std::function<void()>>
1448 ace
void if_else_lane(FuncType true_branch, FuncType false_branch) {
1449 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1458 template <
typename FuncType>
1459 requires std::convertible_to<FuncType, std::function<void(
int)>>
1460 ace
void if_lane_with_index(FuncType true_branch) {
1461 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1468 template <
typename FuncType1,
typename FuncType2>
1469 requires std::convertible_to<FuncType1, std::function<void(
int)>> &&
1470 std::convertible_to<FuncType2, std::function<void(
int)>>
1471 ace
void if_else_lane_with_index(FuncType1 true_branch, FuncType2 false_branch) {
1472 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1482 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1491#ifdef ARGON_PLATFORM_MVE
1492 return mve::max_reduce_max(vec_, vec_) != 0;
1495 utility::constexpr_for<0, lanes, 1>([&]<
int i>() {
1496 if (nonzero[i] == 0) {
1504 template <std::
size_t Index>
1505 std::tuple_element_t<Index, argon_type> get() {
1506#ifdef ARGON_PLATFORM_MVE
1514 template <std::size_t... Ints>
1516 return VectorType{
static_cast<scalar_type>(start + Ints)...};
1528template <
typename T>
1529struct tuple_size<argon::Vector<T>> {
1533template <
size_t Index,
typename T>
1534struct tuple_element<Index, argon::Vector<T>> {
1535 static_assert(Index < argon::Vector<T>::lanes);
Provides utility templates and concepts for type traits and compile-time iteration.
A 128-bit SIMD vector wrapping a scalar type, providing arithmetic, logical, and data-movement operat...
Definition argon_full.hpp:29
Represents a single lane of a SIMD vector with the lane index known at compile time.
Definition lane.hpp:46
ace int lane()
On ARM32, return the local lane index within the 64-bit half-register returned by vec().
Definition lane.hpp:95
ace neon::Vec64_t< scalar_type > vec()
On ARM32, return the 64-bit half-register that contains this lane.
Definition lane.hpp:83
ace scalar_type Get() const
Get the scalar value of this lane.
Definition lane.hpp:74
ace argon_type Load(const scalar_type *ptr)
Load a scalar from ptr into this lane and return the updated vector.
Definition lane.hpp:60
Represents a single lane of a SIMD vector with a runtime-determined index.
Definition lane.hpp:117
ace int lane()
On ARM32, return the local lane index within the 64-bit half-register returned by vec().
Definition lane.hpp:162
ace neon::Vec64_t< scalar_type > vec()
On ARM32, return the 64-bit half-register that contains this lane.
Definition lane.hpp:150
ace scalar_type Get() const
Get the scalar value of this lane.
Definition lane.hpp:139
ace argon_type PairwiseMin(argon_type b) const
Select the maximum of each pair of lanes in the two vectors.
Definition vector.hpp:1171
Lane< simd::Vec128_t< ScalarType > > lane_type
Definition vector.hpp:54
ace argon_type MultiplySubtract(argon_type b, lane_type c) const
Multiply a vector by a lane value and subtract from a third vector.
Definition vector.hpp:526
ace Vector(VectorType vector)
Constructs a Vector from a SIMD vector type.
Definition vector.hpp:74
simd::Vec128_t< ScalarType > vector_type
Definition vector.hpp:56
ace argon_type Modulo(argon_type b) const
Get the modulo of two vectors.
Definition vector.hpp:694
ace argon_bool_type operator<(argon_type b) const
Compare two vectors, checking if this vector is less than the other.
Definition vector.hpp:225
ace argon_type ShiftLeftRound(argon_type b) const
Shift the elements of the vector to the left by a specified number of bits, rounding the result.
Definition vector.hpp:797
std::array< argon_type, 2 > TransposeWith(argon_type b) const
Perform a 2x2 matrix transpose on two vectors, returning two vectors of pairs.
Definition vector.hpp:1357
constexpr Vector(const Vector &other)=default
Copy constructor for the Vector class.
static ace std::array< argon_type, stride > LoadInterleaved(const scalar_type *ptr)
Load multiple vectors from a pointer, de-interleaving.
Definition vector.hpp:968
static ace argon_type Iota(scalar_type start)
Constructs a Vector from an incrementing sequence.
Definition vector.hpp:161
static ace argon_type FromScalar(scalar_type scalar)
Definition vector.hpp:110
ace argon_type Multiply(scalar_type b) const
Multiply a vector by a scalar value.
Definition vector.hpp:431
ace argon_type ReciprocalEstimateRefine(int n_iters=1) const
Compute a refined reciprocal estimate using Newton-Raphson iterations.
Definition vector.hpp:631
ace argon_type MultiplySubtract(argon_type b, argon_type c) const
Multiply two vectors and subtract from a third vector.
Definition vector.hpp:501
ace argon_type Extract(argon_type b) const
Extract n elements from the lower end of the operand, and the remaining elements from the top end of ...
Definition vector.hpp:1292
constexpr VectorType vec() const
Get the underlying SIMD vector.
Definition vector.hpp:279
ace argon_type ReciprocalEstimate() const
1 / value, using an estimate for speed
Definition vector.hpp:572
ace argon_type Multiply(argon_type b) const
Multiply two vectors.
Definition vector.hpp:422
ace argon_bool_type LessThanOrEqual(argon_type b) const
Compare the lanes of two vectors, setting the result lane's bits to ON if a is less than or equal to ...
Definition vector.hpp:743
ace argon_type operator--() const
Decrement the vector by 1 and return the result.
Definition vector.hpp:240
ace argon_type ShiftLeft(const int i) const
Shift the elements of the vector to the left by a specified number of bits.
Definition vector.hpp:358
static ace argon_type Load(const scalar_type *ptr)
Load a vector from a pointer.
Definition vector.hpp:867
ace argon_type operator+(argon_type b) const
Add a vector and return the result.
Definition vector.hpp:207
ace argon_type ShiftLeft(helpers::ArgonFor_t< simd::make_signed_t< Bool_t< VectorType > > > b) const
Shift the elemnets of the vector to the left by a specified number of bits.
Definition vector.hpp:755
ace argon_type Multiply(const_lane_type< LaneIndex > b) const
Multiply a vector by a lane value.
Definition vector.hpp:445
ace argon_type PairwiseAdd(argon_type b) const
Pairwise ops.
Definition vector.hpp:1161
ace argon_type MultiplyAdd(scalar_type b, argon_type c) const
Multiply a vector by a scalar value and add a third vector.
Definition vector.hpp:472
ace argon_bool_type operator>=(argon_type b) const
Compare two vectors, checking if this vector is greater than or equal to the other.
Definition vector.hpp:234
ace argon_type MultiplyAdd(argon_type b, lane_type c) const
Multiply a vector by a lane value and add a third vector.
Definition vector.hpp:477
ace argon_bool_type operator==(argon_type b) const
Compare two vectors for equality.
Definition vector.hpp:219
ace argon_type MultiplyAdd(argon_type b, argon_type c) const
Multiply two vectors and add a third vector.
Definition vector.hpp:452
ace argon_type BitwiseSelect(ArgType true_value, ArgType false_value) const
Bitwise select between two vectors, using the current vector as a mask.
Definition vector.hpp:1240
ace argon_type ShiftLeft(std::make_signed_t< simd::Scalar_t< Bool_t< VectorType > > > n) const
Shift the elements of the vector to the left by a specified number of bits.
Definition vector.hpp:767
ace argon_type BitwiseOrNot(argon_type b) const
Bitwise OR of the vector with the NOT of another vector.
Definition vector.hpp:1214
ace helpers::ArgonFor_t< simd::make_signed_t< Bool_t< VectorType > > > CountLeadingSignBits() const
Count the number of consecutive bits following the sign bit that are set to the same value as the sig...
Definition vector.hpp:1261
static ace argon_type FromLane(argon::ConstLane< LaneIndex, VectorType > lane)
Constructs a Vector from a ConstLane object.
Definition vector.hpp:136
ace argon_type AddSaturate(argon_type b) const
Adds two vectors, saturating the result.
Definition vector.hpp:389
std::array< argon_type, 2 > UnzipWith(argon_type b)
Unzip two vectors, returning two vectors of pairs.
Definition vector.hpp:1334
ace argon_type operator++() const
Increment the vector by 1 and return the result.
Definition vector.hpp:237
ace argon_type MultiplyAddFixedQMax(argon_type b, arg_type c) const
Multiply-add three fixed-point vectors, returning a fixed-point sum.
Definition vector.hpp:659
ace argon_type operator^(argon_type b) const
Bitwise XOR two vectors and return the result.
Definition vector.hpp:249
ace argon_type ReciprocalSqrtStep(argon_type b) const
Newton-Raphson step for reciprocal-sqrt refinement: (3 - a * b) / 2.
Definition vector.hpp:618
ace argon_bool_type Equal(argon_type b) const
Compare the lanes of two vectors, setting the result lane's bits to ON if are equal.
Definition vector.hpp:735
ace void StoreTo(scalar_type *ptr) const
Store the vector to a pointer.
Definition vector.hpp:1141
ConstLane< LaneIndex, simd::Vec128_t< ScalarType > > const_lane_type
Definition vector.hpp:53
ace argon_type MultiplyRoundFixedQMax(lane_type l) const
Multiply a fixed-point vector by a lane value, returning a fixed-point product.
Definition vector.hpp:562
ace argon_type CountActiveBits() const
Count the number of bits that are set to one in the vector.
Definition vector.hpp:1273
ace argon_type MultiplyFixedQMax(scalar_type s) const
Multiply a QMax fixed-point vector by a scalar value, returning a fixed-point product.
Definition vector.hpp:537
ace predicate_type CompareTestNonzero(argon_type b) const
Ands the current vector with the given vector, then checks if nonzero.
Definition vector.hpp:1253
static ace std::array< argon_type, stride > LoadToLaneInterleaved(std::array< argon_type, stride > multi, const scalar_type *ptr)
Load a value from a pointer into a vector at the lane index lane, de-interleaving.
Definition vector.hpp:1060
ace argon_type PairwiseMax(argon_type b) const
Select the maximum of each pair of lanes in the two vectors.
Definition vector.hpp:1166
ace argon_type operator/(argon_type b) const
Divide a vector and return the result.
Definition vector.hpp:216
ace argon_type BitwiseNot() const
Bitwise ops.
Definition vector.hpp:1177
ace argon_type Max(argon_type b) const
Compare the lanes of two vectors, copying the larger of each lane to the result.
Definition vector.hpp:716
static ace argon_type FromLane(argon::Lane< IntrinsicType > lane)
Definition vector.hpp:123
constexpr Vector & operator=(Vector &&other)=default
Move assignment operator for the Vector class.
ace argon_type ShiftLeftInsert(argon_type b) const
Shift the elements of the vector to the left by a specified number of bits, and then OR the result wi...
Definition vector.hpp:814
ace const lane_type GetLane(const size_t i) const
Get a single lane of the vector by index.
Definition vector.hpp:296
ace argon_type BitwiseAnd(argon_type b) const
Bitwise AND of the vector with another vector.
Definition vector.hpp:1186
ace argon_type MultiplyAdd(argon_type b, const_lane_type< LaneIndex > c) const
Multiply a vector by a lane value and add a third vector.
Definition vector.hpp:488
ace argon_type Modulo(scalar_type b) const
Get the modulo of a vector and a scalar value.
Definition vector.hpp:706
ace argon_type Popcount() const
Count the number of bits that are set to one in the vector.
Definition vector.hpp:1286
ace argon_bool_type LessThan(argon_type b) const
Compare the lanes of two vectors, setting the result lane's bits to ON if a is less than b.
Definition vector.hpp:751
ace argon_type ShiftRight(const int i) const
Shift the elements of the vector to the right by a specified number of bits.
Definition vector.hpp:355
ace argon_type ShiftLeftRoundSaturate(argon_type b) const
Shift the elements of the vector to the left by a specified number of bits, rounding and saturating t...
Definition vector.hpp:800
ace Vector(scalar_type scalar)
Constructs a Vector from a scalar value.
Definition vector.hpp:79
ace argon_type ShiftRight() const
Shift the elements of the vector to the right by a specified number of bits.
Definition vector.hpp:820
ace argon_type Negate() const
Bitwise negate the vector and return the result.
Definition vector.hpp:361
ace void StoreLaneTo(scalar_type *ptr)
Store a lane of the vector to a pointer.
Definition vector.hpp:1147
ace argon_type Multiply(lane_type b) const
Multiply a vector by a lane value.
Definition vector.hpp:441
ace argon_type MultiplySubtract(argon_type b, scalar_type c) const
Multiply a vector by a scalar value and subtract from a third vector.
Definition vector.hpp:511
ace argon_type MultiplyAdd(const_lane_type< LaneIndex > b, argon_type c) const
Multiply a vector by a lane value and add a third vector.
Definition vector.hpp:494
ace argon_type MultiplyRoundFixedQMax(scalar_type s) const
Multiply a fixed-point vector by a scalar value, returning a fixed-point product.
Definition vector.hpp:555
ace argon_bool_type GreaterThanOrEqual(argon_type b) const
Compare the lanes of two vectors, setting the result lane's bits to ON if a is greater than or equal ...
Definition vector.hpp:739
ace argon_bool_type operator>(argon_type b) const
Compare two vectors, checking if this vector is greater than the other.
Definition vector.hpp:228
ace argon_type operator<<(const int i) const
Shift the elements of the vector to the left by a specified number of bits.
Definition vector.hpp:270
ace argon_type AddHalve(argon_type b) const
Adds two vectors, halving the result.
Definition vector.hpp:380
static ace std::array< argon_type, stride > LoadGatherOffsetIndexInterleaved(const scalar_type *base_ptr, helpers::ArgonFor_t< simd::make_unsigned_t< Bool_t< VectorType > > > offset_vector)
Perform a Load-Gather of interleaved elements.
Definition vector.hpp:1077
ace argon_type Divide(argon_type b) const
Divide two vectors.
Definition vector.hpp:683
ace argon_type ShiftRightRound() const
Shift the elements of the vector to the right by a specified number of bits, rounding the result.
Definition vector.hpp:830
Bool_t< simd::Vec128_t< ScalarType > > predicate_type
Definition vector.hpp:58
static ace std::array< argon_type, stride > LoadCopyInterleaved(const scalar_type *ptr)
Load multiple vectors from a pointer, duplicating the value across all lanes.
Definition vector.hpp:996
static ace int size()
Get the number of elements.
Definition vector.hpp:1376
static ace argon_type LoadGatherOffsetBytes(const scalar_type *base, helpers::ArgonFor_t< simd::make_unsigned_t< Bool_t< VectorType > > > offset_vector)
Using a base address and a vector of offset bytes and a base pointer, create a new vector.
Definition vector.hpp:891
ace argon_bool_type GreaterThan(argon_type b) const
Compare the lanes of two vectors, setting the result lane's bits to ON if a is greater than b.
Definition vector.hpp:747
ace argon_type ReciprocalStep(argon_type b) const
Newton-Raphson step for reciprocal refinement: (2 - a * b) / 2.
Definition vector.hpp:605
ace std::array< argon_type, 2 > ZipWith(argon_type b) const
Zip two vectors together, returning two vectors of pairs.
Definition vector.hpp:1313
ace argon_type operator-(argon_type b) const
Subtract a vector and return the result.
Definition vector.hpp:210
ace argon_type MultiplyRoundAddFixedQMax(argon_type b, arg_type c) const
Multiply-round-add three fixed-point vectors, returning a fixed-point sum.
Definition vector.hpp:668
helpers::ArgonFor_t< simd::Vec128_t< ScalarType > > argon_type
Definition vector.hpp:57
static ace argon_type LoadScalar(const scalar_type *ptr)
Constructs a Vector from a scalar pointer.
Definition vector.hpp:104
ace argon_type ShiftRightAccumulateRound(argon_type b) const
Shift the elements of the b vector to the right by a specified number of bits, and then add the resul...
Definition vector.hpp:850
ace argon_type operator*(argon_type b) const
Multiply a vector and return the result.
Definition vector.hpp:213
ace predicate_type TestNonzero() const
Ands the current vector with the given vector, then checks if nonzero.
Definition vector.hpp:1256
static ace argon_type LoadCopy(const scalar_type *ptr)
Load a vector from a pointer, duplicating the value across all lanes.
Definition vector.hpp:876
ace argon_type LoadToLane(const scalar_type *ptr)
Load a lane from a pointer.
Definition vector.hpp:957
ace argon_type SubtractAbs(argon_type b) const
Subtract two vectors, taking the absolute value of the result.
Definition vector.hpp:409
ace argon_type ShiftLeft() const
Shift the elements of the vector to the left by a specified number of bits.
Definition vector.hpp:781
ace const_lane_type< lanes - 1 > LastLane()
Get the last lane of the vector.
Definition vector.hpp:352
ace argon_type ShiftLeftSaturate(helpers::ArgonFor_t< simd::make_signed_t< Bool_t< VectorType > > > b) const
Shift the elements of the vector to the left by a specified number of bits, saturating the result.
Definition vector.hpp:790
ace argon_type MultiplyFixedQMax(lane_type l) const
Multiply a QMax fixed-point vector by a lane value, returning a fixed-point product.
Definition vector.hpp:542
ace argon_type MultiplySubtract(scalar_type b, argon_type c) const
Multiply a vector by a scalar value and subtract from a third vector.
Definition vector.hpp:521
ace argon_bool_type operator<=(argon_type b) const
Compare two vectors, checking if this vector is less than or equal to the other.
Definition vector.hpp:231
ace argon_type ShiftLeftSaturate() const
Shift the elements of the vector to the left by a specified number of bits, saturating the result.
Definition vector.hpp:804
ace argon_type operator&(argon_type b) const
Bitwise AND two vectors and return the result.
Definition vector.hpp:243
ace argon_type MultiplyRoundFixedQMax(argon_type v) const
Multiply two fixed-point vectors, returning a fixed-point product.
Definition vector.hpp:549
ace argon_type SubtractSaturate(argon_type b) const
Subtract two vectors, saturating the result.
Definition vector.hpp:405
static ace std::array< argon_type, Stride > LoadToLaneInterleaved(simd::MultiVector_t< VectorType, Stride > multi, const scalar_type *ptr)
Load a value from a pointer into a vector at the lane index lane, de-interleaving.
Definition vector.hpp:1026
ace argon_type ReciprocalSqrtEstimateRefine(int n_iters=1) const
Compute a refined reciprocal-sqrt estimate using Newton-Raphson iterations.
Definition vector.hpp:644
static ace std::array< argon_type, n > LoadMulti(const scalar_type *ptr)
Load n vectors from a single contiguous set of memory.
Definition vector.hpp:1097
static ace argon_type LoadGatherOffsetIndex(const scalar_type *base, helpers::ArgonFor_t< simd::make_unsigned_t< Bool_t< VectorType > > > offset_vector)
Using a base address and a vector of offset indices and a base pointer, create a new vector.
Definition vector.hpp:926
helpers::ArgonFor_t< predicate_type > argon_bool_type
Definition vector.hpp:59
ace argon_type operator|(argon_type b) const
Bitwise OR two vectors and return the result.
Definition vector.hpp:246
ace argon_type MultiplyFixedQMax(argon_type v) const
Multiply two QMax fixed-point vectors, returning a fixed-point product.
Definition vector.hpp:533
ace argon_type MultiplyAdd(argon_type b, scalar_type c) const
Multiply a vector by a scalar value and add a third vector.
Definition vector.hpp:462
simd::Scalar_t< simd::Vec128_t< ScalarType > > scalar_type
Definition vector.hpp:55
ace const const_lane_type< LaneIndex > GetLane() const
Get a single lane of the vector by index.
Definition vector.hpp:334
ace argon_type Select(ArgType true_value, ArgType false_value) const
Bitwise select between two vectors, using the current vector as a mask.
Definition vector.hpp:1247
ace argon_type operator~() const
Bitwise NOT the vector and return the result.
Definition vector.hpp:252
ace Vector(argon::ConstLane< LaneIndex, VectorType > lane)
Constructs a Vector from a ConstLane object.
Definition vector.hpp:92
ace std::array< scalar_type, lanes > to_array()
Convert the vector to an array of scalar values.
Definition vector.hpp:286
ace argon_type Absolute() const
Get the absolute value of the vector.
Definition vector.hpp:568
static constexpr size_t lanes
Definition vector.hpp:62
ace lane_type operator[](const size_t i)
Access a lane of the vector by index.
Definition vector.hpp:258
ace argon_type BitwiseClear(argon_type b) const
Bitwise AND of the vector with the NOT of another vector.
Definition vector.hpp:1233
ace argon_type BitwiseAndNot(argon_type b) const
Bitwise AND of the vector with the NOT of another vector.
Definition vector.hpp:1224
ace argon_type ShiftRightAccumulate(argon_type b) const
Shift the elements of the b vector to the right by a specified number of bits, and then add the resul...
Definition vector.hpp:838
ace argon_type operator>>(const int i) const
Shift the elements of the vector to the right by a specified number of bits.
Definition vector.hpp:261
ace argon_type Add(argon_type b) const
Add two vectors.
Definition vector.hpp:370
ace argon_type BitwiseOr(argon_type b) const
Bitwise OR of the vector with another vector.
Definition vector.hpp:1195
ace argon_type ReciprocalSqrtEstimate() const
1 / sqrt(value), using an estimate for speed
Definition vector.hpp:588
constexpr Vector()=default
The default constructor for the Vector class.
ace const lane_type GetLane(const int i) const
Get a single lane of the vector by index.
Definition vector.hpp:314
constexpr Vector & operator=(const Vector &other)=default
Copy assignment operator for the Vector class.
static ace argon_type GenerateWithIndex(FuncType body)
Constructs a Vector from a function that generates values with an index.
Definition vector.hpp:193
ace argon_bool_type operator!=(argon_type b) const
Compare two vectors for inequality.
Definition vector.hpp:222
ace argon_type CountLeadingZeroBits() const
Count the number of consecutive top bits that are set to zero.
Definition vector.hpp:1269
ace argon_type Min(argon_type b) const
Compare the lanes of two vectors, copying the smaller of each lane to the result.
Definition vector.hpp:725
ace argon_type operator-() const
Negate the SIMD vector and return the result.
Definition vector.hpp:204
ace argon_type SubtractHalve(argon_type b) const
Subtract two vectors, halving the result.
Definition vector.hpp:402
ace argon_type MultiplyAdd(lane_type b, argon_type c) const
Multiply a vector by a lane value and add a third vector.
Definition vector.hpp:483
ace argon_type ShiftRightInsert(argon_type b) const
Shift the elements of the vector to the right by a specified number of bits, ORing the result with th...
Definition vector.hpp:862
ace argon_type SubtractAbsAdd(argon_type b, argon_type c) const
Subtract two vectors, taking the absolute value of the result and adding a third vector.
Definition vector.hpp:413
constexpr Vector(Vector &&other)=default
Move constructor for the Vector class.
ace argon_type Subtract(argon_type b) const
Subtract two vectors.
Definition vector.hpp:392
ace argon_type BitwiseXor(argon_type b) const
Bitwise XOR of the vector with another vector.
Definition vector.hpp:1204
ace Vector(argon::Lane< VectorType > lane)
Constructs a Vector from a Lane object.
Definition vector.hpp:85
static ace argon_type Generate(FuncType body)
Constructs a Vector from a function that generates values.
Definition vector.hpp:176
ace argon_type AddHalveRound(argon_type b) const
Adds two vectors, halving and rounding the result.
Definition vector.hpp:384
ace Lane< const VectorType > operator[](const size_t i) const
Access a lane of the vector by index.
Definition vector.hpp:255
Header file for SIMD features and platform detection.
typename ArgonFor< std::remove_cv_t< T > >::type ArgonFor_t
Helper alias to get the Argon type for a given vector type.
Definition argon_for.hpp:45
Lane deconstruction feature.
Definition argon_full.hpp:399
Helper functions to convert C-style arrays to std::array of Argon types, mimicking std::to_array.
constexpr std::array< helpers::ArgonFor_t< T >, N > to_array(T(&a)[N])
Convert a C-style array of vector types to a std::array of Argon types.
Definition to_array.hpp:29