-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Continue the implementation process of std::simd
Signed-off-by: Ian <[email protected]>
- Loading branch information
Showing
13 changed files
with
595 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,17 @@ | ||
ccm_add_headers( | ||
simd.hpp | ||
arm_detail.hpp | ||
assume_aligned.hpp | ||
const_eval.hpp | ||
constexpr_wrapper.hpp | ||
debug_print.hpp | ||
detail.hpp | ||
may_alias.hpp | ||
simd_intrinsic.hpp | ||
trap.hpp | ||
constexpr_wrapper.hpp | ||
flags.hpp | ||
fwddecl.hpp | ||
may_alias.hpp | ||
simd.hpp | ||
simd_config.hpp | ||
simd_meta.hpp | ||
trap.hpp | ||
vec_detail.hpp | ||
x86_include.hpp | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
#pragma once |
27 changes: 27 additions & 0 deletions
27
include/ccmath/internal/math/runtime/pp/assume_aligned.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
|
||
#pragma once | ||
|
||
#include <cstddef> | ||
|
||
#include "ccmath/internal/predef/attributes/always_inline.hpp" | ||
|
||
#if defined(_MSC_VER) && !defined(__clang__) | ||
#include <cstdint> | ||
#endif | ||
|
||
namespace ccm::pp | ||
{ | ||
template <std::size_t Alignment> | ||
CCM_ALWAYS_INLINE void * assume_aligned(void * ptr) | ||
{ | ||
static_assert((Alignment & (Alignment - 1)) == 0, "Alignment must be a power of 2"); // TODO: Might remove this check not sure if it's necessary | ||
#if defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER)) | ||
return __builtin_assume_aligned(ptr, Alignment); | ||
#elif defined(_MSC_VER) | ||
__assume((reinterpret_cast<std::uintptr_t>(ptr) & (Alignment - 1)) == 0); | ||
return ptr; | ||
#else | ||
return ptr; | ||
#endif | ||
} | ||
} // namespace ccm::pp |
9 changes: 9 additions & 0 deletions
9
include/ccmath/internal/math/runtime/pp/constexpr_wrapper.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,11 @@ | ||
/* | ||
* Copyright (c) Ian Pike | ||
* Copyright (c) CCMath contributors | ||
* | ||
* CCMath is provided under the Apache-2.0 License WITH LLVM-exception. | ||
* See LICENSE for more information. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
*/ | ||
|
||
#pragma once |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
/* | ||
* Copyright (c) Ian Pike | ||
* Copyright (c) CCMath contributors | ||
* | ||
* CCMath is provided under the Apache-2.0 License WITH LLVM-exception. | ||
* See LICENSE for more information. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "ccmath/internal/predef/attributes/always_inline.hpp" | ||
#include "ccmath/internal/support/bits.hpp" | ||
#include "ccmath/internal/support/floating_point_traits.hpp" | ||
|
||
// ReSharper disable once CppUnusedIncludeDirective | ||
#include "assume_aligned.hpp" | ||
#include "fwddecl.hpp" | ||
#include "simd_config.hpp" | ||
|
||
namespace ccm::pp | ||
{ | ||
namespace detail | ||
{ | ||
struct LoadStoreTag | ||
{ | ||
}; | ||
|
||
struct Convert : LoadStoreTag | ||
{ | ||
}; | ||
|
||
template <typename T> | ||
struct ConvertTo : LoadStoreTag | ||
{ | ||
using type = T; | ||
}; | ||
|
||
struct Aligned : LoadStoreTag | ||
{ | ||
template <typename T, typename U> | ||
CCM_SIMD_INTRINSIC static constexpr U * adjust_pointer(U * ptr) | ||
{ | ||
return static_cast<U *>(pp::assume_aligned<simd_alignment_v<T, U>>(ptr)); | ||
} | ||
}; | ||
|
||
template <std::size_t N> | ||
struct Overaligned : LoadStoreTag | ||
{ | ||
static_assert(support::has_single_bit(N)); | ||
|
||
template <typename, typename U> | ||
CCM_SIMD_INTRINSIC static constexpr U * adjust_pointer(U * ptr) | ||
{ | ||
return static_cast<U *>(pp::assume_aligned<N>(ptr)); | ||
} | ||
}; | ||
|
||
struct Streaming : LoadStoreTag | ||
{ | ||
}; | ||
|
||
template <int L1, int L2> | ||
struct Prefetch : LoadStoreTag | ||
{ | ||
template <typename, typename U> | ||
CCM_ALWAYS_INLINE static U * adjust_pointer(U * ptr) | ||
{ | ||
// one read: 0, 0 | ||
// L1: 0, 1 | ||
// L2: 0, 2 | ||
// L3: 0, 3 | ||
// (exclusive cache line) for writing: 1, 0 / 1, 1 | ||
/* constexpr int write = 1; | ||
constexpr int level = 0-3; | ||
__builtin_prefetch(ptr, write, level) | ||
_mm_prefetch(reinterpret_cast<char const*>(ptr), _MM_HINT_T0); | ||
_mm_prefetch(reinterpret_cast<char const*>(ptr), _MM_HINT_T1); | ||
_mm_prefetch(reinterpret_cast<char const*>(ptr), _MM_HINT_T2); | ||
_mm_prefetch(reinterpret_cast<char const*>(ptr), _MM_HINT_ET0); | ||
_mm_prefetch(reinterpret_cast<char const*>(ptr), _MM_HINT_ET1); | ||
_mm_prefetch(reinterpret_cast<char const*>(ptr), _MM_HINT_NTA);*/ | ||
return ptr; | ||
} | ||
}; | ||
|
||
template <typename T> | ||
using is_loadstore_tag = std::is_base_of<LoadStoreTag, T>; | ||
} // namespace detail | ||
|
||
template <typename... Flags> | ||
struct simd_flags | ||
{ | ||
static_assert((detail::is_loadstore_tag<Flags>::value && ...), "All Flags must derive from LoadStoreTag"); | ||
|
||
// ReSharper disable once CppMemberFunctionMayBeStatic | ||
CCM_CONSTEVAL bool is_equal(simd_flags) const { return true; } | ||
|
||
template <typename... Other> | ||
CCM_CONSTEVAL bool is_equal([[maybe_unused]] simd_flags<Other...> other) const | ||
{ | ||
return std::is_same_v<simd_flags<>, decltype(xor_flags(other))>; | ||
} | ||
|
||
template <typename... Other> | ||
CCM_CONSTEVAL bool test(simd_flags<Other...> other) const noexcept | ||
{ | ||
return other.is_equal(and_flags(other)); | ||
} | ||
|
||
friend CCM_CONSTEVAL auto operator|(simd_flags, simd_flags<>) { return simd_flags{}; } | ||
|
||
template <typename T0, typename... More> | ||
friend CCM_CONSTEVAL auto operator|(simd_flags, simd_flags<T0, More...>) | ||
{ | ||
if constexpr ((std::is_same_v<Flags, T0> || ...)) { return simd_flags<Flags...>{} | simd_flags<More...>{}; } | ||
else { return simd_flags<Flags..., T0>{} | simd_flags<More...>{}; } | ||
} | ||
|
||
// ReSharper disable once CppMemberFunctionMayBeStatic | ||
CCM_CONSTEVAL auto and_flags(simd_flags<>) const { return simd_flags<>{}; } | ||
|
||
template <typename T0, typename... More> | ||
CCM_CONSTEVAL auto and_flags(simd_flags<T0, More...>) const | ||
{ | ||
if constexpr ((std::is_same_v<Flags, T0> || ...)) { return simd_flags<T0>{} | (simd_flags{}.and_flags(simd_flags<More...>{})); } | ||
else { return simd_flags{}.and_flags(simd_flags<More...>{}); } | ||
} | ||
|
||
CCM_CONSTEVAL auto xor_flags(simd_flags<>) const { return simd_flags{}; } | ||
|
||
template <typename T0, typename... More> | ||
CCM_CONSTEVAL auto xor_flags(simd_flags<T0, More...>) const | ||
{ | ||
if constexpr ((std::is_same_v<Flags, T0> || ...)) | ||
{ | ||
constexpr auto removed = (std::conditional_t<std::is_same_v<Flags, T0>, simd_flags<>, simd_flags<Flags>>{} | ...); | ||
return removed.xor_flags(simd_flags<More...>{}); | ||
} | ||
else { return (simd_flags{} | simd_flags<T0>{}).xor_flags(simd_flags<More...>{}); } | ||
} | ||
|
||
template <typename F0, typename Tp, typename Ptr> | ||
static constexpr void apply_adjust_pointer(Ptr & ptr) | ||
{ | ||
if constexpr (std::is_same_v<decltype(F0::template adjust_pointer<Tp>(ptr)), void>) { ptr = F0::template adjust_pointer<Tp>(ptr); } | ||
} | ||
|
||
template <typename Tp, typename Up> | ||
static constexpr Up * adjust_pointer(Up * ptr) | ||
{ | ||
(apply_adjust_pointer<Flags, Tp>(ptr), ...); | ||
return ptr; | ||
} | ||
}; | ||
|
||
// [simd.flags] | ||
inline constexpr simd_flags<> simd_flag_default; | ||
|
||
inline constexpr simd_flags<detail::Convert> simd_flag_convert; | ||
|
||
inline constexpr simd_flags<detail::Aligned> simd_flag_aligned; | ||
|
||
template <std::size_t N> | ||
requires(support::has_single_bit(N)) | ||
inline constexpr simd_flags<detail::Overaligned<N>> simd_flag_overaligned; | ||
|
||
// extensions | ||
template <typename T> | ||
inline constexpr simd_flags<detail::ConvertTo<T>> simd_flag_convert_to; | ||
|
||
inline constexpr simd_flags<detail::Streaming> simd_flag_streaming; | ||
|
||
template <int L1, int L2> | ||
inline constexpr simd_flags<detail::Prefetch<L1, L2>> simd_flag_prefetch; | ||
|
||
} // namespace ccm::pp |
Oops, something went wrong.