28#ifndef VC_COMMON_LOADSTOREFLAGS_H_
29#define VC_COMMON_LOADSTOREFLAGS_H_
31#include "../traits/type_traits.h"
33namespace Vc_VERSIONED_NAMESPACE
47namespace LoadStoreFlags
50struct StreamingFlag {};
51struct UnalignedFlag {};
52struct PrefetchFlagBase {};
54template <
size_t L1 = 16 * 64,
size_t L2 = 128 * 64,
typename ExclusiveOrShared_ =
void>
55struct PrefetchFlag :
public PrefetchFlagBase {
56 typedef ExclusiveOrShared_ ExclusiveOrShared;
57 static constexpr size_t L1Stride = L1;
58 static constexpr size_t L2Stride = L2;
59 static constexpr bool IsExclusive = std::is_same<ExclusiveOrShared, Exclusive>::value;
60 static constexpr bool IsShared = std::is_same<ExclusiveOrShared, Shared>::value;
63template<
typename Base,
typename Default,
typename... LoadStoreFlags>
struct ExtractType
67template<
typename Base,
typename Default,
typename T,
typename... LoadStoreFlags>
struct ExtractType<Base, Default, T, LoadStoreFlags...>
69 typedef typename std::conditional<std::is_base_of<Base, T>::value, T,
typename ExtractType<Base, Default, LoadStoreFlags...>::type>::type type;
77#pragma warning(disable: 177)
83template<
typename... Flags>
struct LoadStoreFlags
88 typedef typename ExtractType<PrefetchFlagBase, PrefetchFlag<0, 0>, Flags...>::type Prefetch;
91 constexpr LoadStoreFlags() {}
93 static constexpr bool IsStreaming = !std::is_same<
typename ExtractType<StreamingFlag, void, Flags...>::type,
void>::value;
94 static constexpr bool IsUnaligned = !std::is_same<
typename ExtractType<UnalignedFlag, void, Flags...>::type,
void>::value;
95 static constexpr bool IsAligned = !IsUnaligned;
96 static constexpr bool IsPrefetch = !std::is_same<
typename ExtractType<PrefetchFlagBase, void, Flags...>::type,
void>::value;
97 static constexpr bool IsExclusivePrefetch = Prefetch::IsExclusive;
98 static constexpr bool IsSharedPrefetch = Prefetch::IsShared;
99 static constexpr size_t L1Stride = Prefetch::L1Stride;
100 static constexpr size_t L2Stride = Prefetch::L2Stride;
102 typedef LoadStoreFlags<typename std::conditional<std::is_same<Flags, UnalignedFlag>::value, void, Flags>::type...> UnalignedRemoved;
108 typedef typename std::conditional<IsAligned && !IsStreaming, void *, void>::type EnableIfAligned;
109 typedef typename std::conditional<IsAligned && IsStreaming, void *, void>::type EnableIfStreaming;
110 typedef typename std::conditional<IsUnaligned && !IsStreaming, void *, void>::type EnableIfUnalignedNotStreaming;
111 typedef typename std::conditional<IsUnaligned && IsStreaming, void *, void>::type EnableIfUnalignedAndStreaming;
112 typedef typename std::conditional<IsUnaligned , void *, void>::type EnableIfUnaligned;
113 typedef typename std::conditional<!IsUnaligned , void *, void>::type EnableIfNotUnaligned;
114 typedef typename std::conditional<IsPrefetch , void *, void>::type EnableIfPrefetch;
115 typedef typename std::conditional<!IsPrefetch , void *, void>::type EnableIfNotPrefetch;
121template<>
struct LoadStoreFlags<>
123 constexpr LoadStoreFlags() {}
125 static constexpr bool IsStreaming =
false;
126 static constexpr bool IsUnaligned =
false;
127 static constexpr bool IsAligned = !IsUnaligned;
128 static constexpr bool IsPrefetch =
false;
129 static constexpr bool IsExclusivePrefetch =
false;
130 static constexpr bool IsSharedPrefetch =
false;
131 static constexpr size_t L1Stride = 0;
132 static constexpr size_t L2Stride = 0;
133 typedef void* EnableIfAligned;
134 typedef void* EnableIfNotUnaligned;
135 typedef void* EnableIfNotPrefetch;
146template<
typename... LFlags,
typename... RFlags>
147constexpr LoadStoreFlags<LFlags..., RFlags...> operator|(LoadStoreFlags<LFlags...>, LoadStoreFlags<RFlags...>)
149 return LoadStoreFlags<LFlags..., RFlags...>();
154using LoadStoreFlags::PrefetchFlag;
156typedef LoadStoreFlags::LoadStoreFlags<> AlignedTag;
157typedef LoadStoreFlags::LoadStoreFlags<LoadStoreFlags::StreamingFlag> StreamingTag;
158typedef LoadStoreFlags::LoadStoreFlags<LoadStoreFlags::UnalignedFlag> UnalignedTag;
220template <size_t L1 = PrefetchFlag<>::L1Stride,
221 size_t L2 = PrefetchFlag<>::L2Stride,
222 typename ExclusiveOrShared = PrefetchFlag<>::ExclusiveOrShared>
223struct Prefetch :
public LoadStoreFlags::LoadStoreFlags<PrefetchFlag<L1, L2, ExclusiveOrShared>>
230template <
typename... Ts>
231struct is_loadstoreflag_internal<LoadStoreFlags::LoadStoreFlags<Ts...>> :
public std::true_type
236template <
size_t L1,
size_t L2,
typename ExclusiveOrShared>
237struct is_loadstoreflag_internal<Prefetch<L1, L2, ExclusiveOrShared>> :
public std::true_type
constexpr LoadStoreFlags::LoadStoreFlags< PrefetchFlag<> > PrefetchDefault
Use this object for a flags parameter to request default software prefetches to be emitted.
constexpr UnalignedTag Unaligned
Use this object for a flags parameter to request unaligned loads and stores.
constexpr AlignedTag Aligned
Use this object for a flags parameter to request aligned loads and stores.
constexpr StreamingTag Streaming
Use this object for a flags parameter to request streaming loads and stores.
UnalignedTag DefaultLoadTag
The default load tag type uses unaligned (non-streaming) loads.
UnalignedTag DefaultStoreTag
The default store tag type uses unaligned (non-streaming) stores.
Hint for Prefetch to select prefetches that mark the memory as exclusive.
Hint for Prefetch to select prefetches that mark the memory as shared.