simd constexpr vec: fix errors when building w/ gcc

This commit is contained in:
sharkautarch 2024-09-12 11:30:57 -04:00
parent 2c236f4e1a
commit bc5c6727f4
No known key found for this signature in database
GPG Key ID: F270CA9462164405
2 changed files with 26 additions and 13 deletions

View File

@ -12,10 +12,21 @@ namespace glm::detail
using PaddedVec = PaddedGccVec<Lx, Tx, Qx, detail::BVecNeedsPadding<Lx, Tx, Qx>()>;
using gcc_vec_t = PaddedVec<L, T, Q>::GccV;
using data_t = typename detail::storage<L, T, detail::is_aligned<Q>::value>::type;
static inline auto gcc_vec_to_data(PaddedVec<L, T, Q> v) {
if constexpr (L == 3 && !BIsAlignedQ<Q>()) {
data_t d;
std::memcpy(&d, &v, sizeof(d));
return d;
} else {
return std::bit_cast<data_t>(v);
}
}
static inline auto simd_ctor_scalar(arithmetic auto scalar) {
PaddedVec<L, T, Q> v = {};
v.gcc_vec = v.gcc_vec + ( (T)scalar );
return std::bit_cast<data_t>(v);
return gcc_vec_to_data(v);
}
template <length_t Lx, typename Tx, qualifier Qx> requires (Lx == L)
@ -24,7 +35,7 @@ namespace glm::detail
using OtherPaddedVec = PaddedVec<Lx, Tx, Qx>;
OtherPaddedVec o = std::bit_cast<OtherPaddedVec>(v.data);
PaddedVec<L, T, Q> converted = {.gcc_vec=__builtin_convertvector(o.gcc_vec, gcc_vec_t)};
return std::bit_cast<data_t>(converted);
return gcc_vec_to_data(converted);
}
template <length_t Lx, typename Tx, qualifier Qx> requires (Lx != L && Lx < L)
@ -39,7 +50,7 @@ namespace glm::detail
}
PaddedVec<L, T, Q> converted = {.gcc_vec=__builtin_convertvector(oExpanded.gcc_vec, gcc_vec_t)};
return std::bit_cast<data_t>(converted);
return gcc_vec_to_data(converted);
}
template<arithmetic... A>
@ -54,7 +65,7 @@ namespace glm::detail
using OtherPaddedVec = PaddedVec<L, typename GetFirstType<A...>::FirstTx, Q>;
OtherPaddedVec o = {.gcc_vec={scalars...}};
PaddedVec<L, T, Q> converted = {.gcc_vec=__builtin_convertvector(o.gcc_vec, gcc_vec_t)};
return std::bit_cast<data_t>(converted);
return gcc_vec_to_data(converted);
}
};
}

View File

@ -12,6 +12,7 @@
#include <cstddef>
#include <array>
#include <variant>
#include <cstring>
namespace glm
{
template <qualifier Q>
@ -37,35 +38,36 @@ namespace glm
namespace detail
{
template <length_t L, typename T, qualifier Q>
using ArrT = T[L];
using _ArrT = T[L];
template <length_t L, typename T, qualifier Q>
using _data_t = typename detail::storage<L, T, detail::is_aligned<Q>::value>::type;
template <length_t L, typename T, qualifier Q>
using GccV = T __attribute__(( vector_size(sizeof(T)*L), aligned(alignof(_data_t<L, T, Q>)) ));
struct GccVExt {
typedef T GccV __attribute__(( vector_size(sizeof(T)*L), aligned(alignof(_data_t<L, T, Q>)) ));
};
template <length_t L, typename T, qualifier Q>
consteval bool BDataNeedsPadding() {
return sizeof(_data_t<L,T,Q>) > sizeof(ArrT<L,T,Q>);
return sizeof(_data_t<L,T,Q>) > sizeof(_ArrT<L,T,Q>);
}
template <length_t L, typename T, qualifier Q>
consteval bool BVecNeedsPadding() {
return sizeof(_data_t<L,T,Q>) > sizeof(GccV<L,T,Q>);
return sizeof(_data_t<L,T,Q>) > sizeof(typename GccVExt<L,T,Q>::GccV);
}
template <length_t L, typename T, qualifier Q, bool NeedsPadding>
struct VecDataArray;
template <length_t L, typename T, qualifier Q>
struct VecDataArray<L, T, Q, true> {
using ArrT = ArrT<L, T, Q>;
using ArrT = _ArrT<L, T, Q>;
using data_t = _data_t<L,T,Q>;
ArrT p;
std::byte padding[sizeof(data_t) - sizeof(ArrT)];
};
template <length_t L, typename T, qualifier Q>
struct VecDataArray<L, T, Q, false> {
using ArrT = ArrT<L, T, Q>;
using ArrT = _ArrT<L, T, Q>;
ArrT p;
};
@ -74,7 +76,7 @@ namespace glm
template <length_t L, typename T, qualifier Q>
struct PaddedGccVec<L, T, Q, true> {
using GccV = GccV<L, T,Q>;
using GccV = typename GccVExt<L, T,Q>::GccV;
using data_t = _data_t<L, T, Q>;
GccV gcc_vec;
std::byte padding[sizeof(data_t) - sizeof(GccV)];
@ -82,7 +84,7 @@ namespace glm
template <length_t L, typename T, qualifier Q>
struct PaddedGccVec<L, T, Q, false> {
using GccV = GccV<L, T,Q>;
using GccV = typename GccVExt<L, T,Q>::GccV;
GccV gcc_vec;
};
}