1 /* This file is part of the Vc library.
3 Copyright (C) 2010-2012 Matthias Kretz <kretz@kde.org>
5 Vc is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation, either version 3 of
8 the License, or (at your option) any later version.
10 Vc is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with Vc. If not, see <http://www.gnu.org/licenses/>.
20 #ifndef VC_COMMON_STORAGE_H
21 #define VC_COMMON_STORAGE_H
23 #include "aliasingentryhelper.h"
33 template<typename _VectorType, typename _EntryType, typename VectorTypeBase = _VectorType> class VectorMemoryUnion
36 typedef _VectorType VectorType;
37 typedef _EntryType EntryType;
38 typedef EntryType AliasingEntryType Vc_MAY_ALIAS;
39 Vc_ALWAYS_INLINE VectorMemoryUnion() { assertCorrectAlignment(&v()); }
40 #if defined VC_ICC || defined VC_MSVC
41 Vc_ALWAYS_INLINE VectorMemoryUnion(const VectorType &x) { data.v = x; assertCorrectAlignment(&data.v); }
42 Vc_ALWAYS_INLINE VectorMemoryUnion &operator=(const VectorType &x) {
43 data.v = x; return *this;
46 Vc_ALWAYS_INLINE Vc_PURE VectorType &v() { return reinterpret_cast<VectorType &>(data.v); }
47 Vc_ALWAYS_INLINE Vc_PURE const VectorType &v() const { return reinterpret_cast<const VectorType &>(data.v); }
50 Vc_ALWAYS_INLINE Vc_PURE AliasingEntryHelper<VectorMemoryUnion> m(size_t index) {
51 return AliasingEntryHelper<VectorMemoryUnion>(this, index);
53 Vc_ALWAYS_INLINE void assign(size_t index, EntryType x) {
56 Vc_ALWAYS_INLINE Vc_PURE EntryType read(size_t index) const {
60 Vc_ALWAYS_INLINE Vc_PURE EntryType &m(size_t index) {
65 Vc_ALWAYS_INLINE Vc_PURE EntryType m(size_t index) const {
69 #ifdef VC_COMPILE_BENCHMARKS
73 union VectorScalarUnion {
75 EntryType m[sizeof(VectorTypeBase)/sizeof(EntryType)];
78 Vc_ALWAYS_INLINE VectorMemoryUnion(VectorType x) : data(x) { assertCorrectAlignment(&data); }
79 Vc_ALWAYS_INLINE VectorMemoryUnion &operator=(VectorType x) {
80 data = x; return *this;
83 Vc_ALWAYS_INLINE Vc_PURE VectorType &v() { return data; }
84 Vc_ALWAYS_INLINE Vc_PURE const VectorType &v() const { return data; }
86 Vc_ALWAYS_INLINE Vc_PURE AliasingEntryType &m(size_t index) {
87 return reinterpret_cast<AliasingEntryType *>(&data)[index];
90 Vc_ALWAYS_INLINE Vc_PURE EntryType m(size_t index) const {
91 return reinterpret_cast<const AliasingEntryType *>(&data)[index];
95 #ifdef VC_COMPILE_BENCHMARKS
102 #if VC_GCC == 0x40700 || (VC_GCC >= 0x40600 && VC_GCC <= 0x40603)
103 // workaround bug 52736 in GCC
104 template<typename T, typename V> static Vc_ALWAYS_INLINE Vc_CONST T &vectorMemoryUnionAliasedMember(V *data, size_t index) {
105 if (__builtin_constant_p(index) && index == 0) {
107 asm("mov %1,%0" : "=r"(ret) : "r"(data));
110 return reinterpret_cast<T *>(data)[index];
113 template<> Vc_ALWAYS_INLINE Vc_PURE VectorMemoryUnion<__m128d, double>::AliasingEntryType &VectorMemoryUnion<__m128d, double>::m(size_t index) {
114 return vectorMemoryUnionAliasedMember<AliasingEntryType>(&data, index);
116 template<> Vc_ALWAYS_INLINE Vc_PURE VectorMemoryUnion<__m128i, long long>::AliasingEntryType &VectorMemoryUnion<__m128i, long long>::m(size_t index) {
117 return vectorMemoryUnionAliasedMember<AliasingEntryType>(&data, index);
119 template<> Vc_ALWAYS_INLINE Vc_PURE VectorMemoryUnion<__m128i, unsigned long long>::AliasingEntryType &VectorMemoryUnion<__m128i, unsigned long long>::m(size_t index) {
120 return vectorMemoryUnionAliasedMember<AliasingEntryType>(&data, index);
124 } // namespace Common
126 } // namespace AliRoot
128 #include "undomacros.h"
130 #endif // VC_COMMON_STORAGE_H