4#include "native/mask_traits.h"
5#include "native/value_traits.h"
42 static_assert(
sizeof(float) == 4 && std::numeric_limits<float>::is_iec559 &&
43 std::numeric_limits<float>::radix == 2 && std::numeric_limits<float>::digits == 24 &&
44 std::numeric_limits<float>::min_exponent == -125 && std::numeric_limits<float>::max_exponent == 128,
45 "native math requires IEEE 754 binary32 float");
56 template <
class T>
concept simd_integer_element =
57 std::same_as<T,int8_t> || std::same_as<T,int16_t> ||
58 std::same_as<T,int32_t> || std::same_as<T,int64_t> ||
59 std::same_as<T,uint8_t> || std::same_as<T,uint16_t> ||
60 std::same_as<T,uint32_t> || std::same_as<T,uint64_t>;
64 template<
class V>
requires requires {
typename V::value_type; } &&
65 (std::same_as<typename V::value_type,float> ||
66 std::same_as<typename V::value_type,std::int32_t> ||
67 std::same_as<typename V::value_type,std::uint32_t>)
75 template <std::
size_t K>
struct imm_t {
76 static constexpr std::size_t value = K;
88 template<
class U>
requires (std::is_unsigned_v<U> && !std::same_as<U,bool> && (
sizeof(U)==1 ||
sizeof(U)==2 ||
sizeof(U)==4 ||
sizeof(U)==8))
120 template<
class T>
concept simd_mask_element=detail::is_mask_lane<T>;
133 template <
class T>
concept simd_custom_element =
requires {
137 template<
class V,
class U,
class=
void>
struct memory_architecture : value_architecture<V> {};
138 template<
class V,simd_custom_element U>
139 requires std::same_as<typename V::value_type,typename simd_traits<U>::storage_type> &&
140 value_architecture<V>::known &&
141 value_architecture<typename V::template rebind<U>>::known
142 struct memory_architecture<V,U,
std::void_t<typename V::template rebind<U>>> {
143 static constexpr isa<> value=value_architecture_v<V> &
144 value_architecture_v<typename V::template rebind<U>>;
145 static constexpr bool known=
true;
147 template<
class V,
class U>
inline constexpr isa<> memory_architecture_v=memory_architecture<V,U>::value;
154 template<
class V, std::
size_t L>
struct register_memory;
171 template<
class T, std::
size_t N, isa<> Arch>
struct simd;
179 template<
class T, std::
size_t N, isa<> Arch>
187 template<std::
size_t N, isa<> Arch>
193 template<
class U>
requires requires {
typename mask_lane<U>; }
196 namespace detail {
template<
class T,std::
size_t N,isa<> Arch>
struct swizzle_access {}; }
200 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
203 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
206 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
209 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
212 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
215 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
218 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
221 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
224 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
227 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
230 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
233 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
236 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
239 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
242 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
245 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
248 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
251 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
254 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
257 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
260 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
263 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
266 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
269 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
272 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
275 template<
class T,
class U,std::
size_t N,std::
size_t M,isa<> A,isa<> B>
requires(A!=B || (N!=M && (N==2 || N==3 || M==2 || M==3)))
284 template <std::
size_t Alignment = 1, simd_access Access = simd_access::ordinary>
286 static_assert(Alignment > 0 && (Alignment & (Alignment - 1)) == 0);
287 static constexpr std::size_t alignment = Alignment;
288 static constexpr simd_access requested_access = Access;
290 static constexpr bool non_temporal =
false;
Compiler attributes for host code, with shader-safe shared modifiers.
#define native_inline
inline [[always_inline]]
#define native_nodiscard
C++17 [[nodiscard]].
#define native_const
[[const]] is not const
#define native_pure
[[pure]]
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
Standard-library adaptations documented here for SIMD value types.
static constexpr mask_lane from_bits(U value) noexcept
Normalize nonzero bits to a true, all-one lane.
friend constexpr bool operator==(mask_lane, mask_lane) noexcept=default
Compare the two canonical lane truth values and return bool.
friend constexpr mask_lane operator&(mask_lane a, mask_lane b) noexcept
Bitwise AND of corresponding lane representations.
friend constexpr mask_lane operator|(mask_lane a, mask_lane b) noexcept
Bitwise OR of corresponding lane representations.
friend constexpr mask_lane operator^(mask_lane a, mask_lane b) noexcept
Bitwise XOR of corresponding lane representations.
friend constexpr mask_lane operator~(mask_lane a) noexcept
Invert each lane truth value, preserving the mask representation.
constexpr bool to_bool() const noexcept
Return the lane truth value.
constexpr mask_lane() noexcept=default
Initialize this lane to false.
constexpr U to_bits() const noexcept
Return the canonical zero or all-one representation.
friend constexpr mask_lane operator!(mask_lane a) noexcept
Return the lane-wise logical complement, retaining this mask type.
Omitted architecture arguments use the native.simd provider's baseline.