28 #ifndef VC_COMMON_X86_PREFETCHES_H_
29 #define VC_COMMON_X86_PREFETCHES_H_
31 #include <xmmintrin.h>
34 namespace Vc_VERSIONED_NAMESPACE
39 static constexpr
int exclusive_hint = 0;
43 template <
typename ExclusiveOrShared = Vc::Shared>
46 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
47 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)), _MM_HINT_NTA);
49 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)),
50 static_cast<decltype(_MM_HINT_NTA)
>(_MM_HINT_NTA | exclusive_hint));
53 template <
typename ExclusiveOrShared = Vc::Shared>
56 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
57 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)), _MM_HINT_T0);
59 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)),
60 static_cast<decltype(_MM_HINT_T0)
>(_MM_HINT_T0 | exclusive_hint));
63 template <
typename ExclusiveOrShared = Vc::Shared>
66 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
67 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)), _MM_HINT_T1);
69 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)),
70 static_cast<decltype(_MM_HINT_T1)
>(_MM_HINT_T1 | exclusive_hint));
73 template <
typename ExclusiveOrShared = Vc::Shared>
76 if (std::is_same<ExclusiveOrShared, Vc::Shared>::value) {
77 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)), _MM_HINT_T2);
79 _mm_prefetch(
static_cast<char *
>(
const_cast<void *
>(addr)),
80 static_cast<decltype(_MM_HINT_T2)
>(_MM_HINT_T2 | exclusive_hint));
87 template<
size_t L1,
size_t L2,
bool UseExclusivePrefetch> Vc_INTRINSIC
void handlePrefetch(
const void *addr_,
typename std::enable_if<L1 != 0 && L2 != 0, void *>::type =
nullptr)
89 const char *addr =
static_cast<const char *
>(addr_);
90 prefetchClose<typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L1);
91 prefetchMid <typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L2);
93 template<
size_t L1,
size_t L2,
bool UseExclusivePrefetch> Vc_INTRINSIC
void handlePrefetch(
const void *addr_,
typename std::enable_if<L1 == 0 && L2 != 0, void *>::type =
nullptr)
95 const char *addr =
static_cast<const char *
>(addr_);
96 prefetchMid <typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L2);
98 template<
size_t L1,
size_t L2,
bool UseExclusivePrefetch> Vc_INTRINSIC
void handlePrefetch(
const void *addr_,
typename std::enable_if<L1 != 0 && L2 == 0, void *>::type =
nullptr)
100 const char *addr =
static_cast<const char *
>(addr_);
101 prefetchClose<typename std::conditional<UseExclusivePrefetch, Vc::Exclusive, Vc::Shared>::type>(addr + L1);
103 template<
size_t L1,
size_t L2,
bool UseExclusivePrefetch> Vc_INTRINSIC
void handlePrefetch(
const void *,
typename std::enable_if<L1 == 0 && L2 == 0, void *>::type =
nullptr)
107 template<
typename Flags> Vc_INTRINSIC
void handleLoadPrefetches(
const void * , Flags,
typename Flags::EnableIfNotPrefetch =
nullptr) {}
108 template<
typename Flags> Vc_INTRINSIC
void handleLoadPrefetches(
const void *addr, Flags,
typename Flags::EnableIfPrefetch =
nullptr)
111 handlePrefetch<Flags::L1Stride, Flags::L2Stride, Flags::IsExclusivePrefetch>(addr);
114 template<
typename Flags> Vc_INTRINSIC
void handleStorePrefetches(
const void * , Flags,
typename Flags::EnableIfNotPrefetch =
nullptr) {}
115 template<
typename Flags> Vc_INTRINSIC
void handleStorePrefetches(
const void *addr, Flags,
typename Flags::EnableIfPrefetch =
nullptr)
118 handlePrefetch<Flags::L1Stride, Flags::L2Stride, !Flags::IsSharedPrefetch>(addr);
132 #endif // VC_COMMON_X86_PREFETCHES_H_