]> git.uio.no Git - u/mrichter/AliRoot.git/blob - Vc/include/Vc/common/storage.h
update to Vc 0.7.3-dev
[u/mrichter/AliRoot.git] / Vc / include / Vc / common / storage.h
1 /*  This file is part of the Vc library.
2
3     Copyright (C) 2010-2012 Matthias Kretz <kretz@kde.org>
4
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.
9
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.
14
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/>.
17
18 */
19
20 #ifndef VC_COMMON_STORAGE_H
21 #define VC_COMMON_STORAGE_H
22
23 #include "aliasingentryhelper.h"
24 #include "macros.h"
25 #include "types.h"
26
27 namespace AliRoot {
28 namespace Vc
29 {
30 namespace Common
31 {
32
33 template<typename _VectorType, typename _EntryType, typename VectorTypeBase = _VectorType> class VectorMemoryUnion
34 {
35     public:
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;
44         }
45
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); }
48
49 #if defined VC_ICC
50         Vc_ALWAYS_INLINE Vc_PURE AliasingEntryHelper<VectorMemoryUnion> m(size_t index) {
51             return AliasingEntryHelper<VectorMemoryUnion>(this, index);
52         }
53         Vc_ALWAYS_INLINE void assign(size_t index, EntryType x) {
54             data.m[index] = x;
55         }
56         Vc_ALWAYS_INLINE Vc_PURE EntryType read(size_t index) const {
57             return data.m[index];
58         }
59 #else
60         Vc_ALWAYS_INLINE Vc_PURE EntryType &m(size_t index) {
61             return data.m[index];
62         }
63 #endif
64
65         Vc_ALWAYS_INLINE Vc_PURE EntryType m(size_t index) const {
66             return data.m[index];
67         }
68
69 #ifdef VC_COMPILE_BENCHMARKS
70     public:
71 #endif
72     private:
73         union VectorScalarUnion {
74             VectorTypeBase v;
75             EntryType m[sizeof(VectorTypeBase)/sizeof(EntryType)];
76         } data;
77 #else
78         Vc_ALWAYS_INLINE VectorMemoryUnion(VectorType x) : data(x) { assertCorrectAlignment(&data); }
79         Vc_ALWAYS_INLINE VectorMemoryUnion &operator=(VectorType x) {
80             data = x; return *this;
81         }
82
83         Vc_ALWAYS_INLINE Vc_PURE VectorType &v() { return data; }
84         Vc_ALWAYS_INLINE Vc_PURE const VectorType &v() const { return data; }
85
86         Vc_ALWAYS_INLINE Vc_PURE AliasingEntryType &m(size_t index) {
87             return reinterpret_cast<AliasingEntryType *>(&data)[index];
88         }
89
90         Vc_ALWAYS_INLINE Vc_PURE EntryType m(size_t index) const {
91             return reinterpret_cast<const AliasingEntryType *>(&data)[index];
92         }
93
94     private:
95 #ifdef VC_COMPILE_BENCHMARKS
96     public:
97 #endif
98         VectorType data;
99 #endif
100 };
101
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) {
106         T *ret;
107         asm("mov %1,%0" : "=r"(ret) : "r"(data));
108         return *ret;
109     } else {
110         return reinterpret_cast<T *>(data)[index];
111     }
112 }
113 template<> Vc_ALWAYS_INLINE Vc_PURE VectorMemoryUnion<__m128d, double>::AliasingEntryType &VectorMemoryUnion<__m128d, double>::m(size_t index) {
114     return vectorMemoryUnionAliasedMember<AliasingEntryType>(&data, index);
115 }
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);
118 }
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);
121 }
122 #endif
123
124 } // namespace Common
125 } // namespace Vc
126 } // namespace AliRoot
127
128 #include "undomacros.h"
129
130 #endif // VC_COMMON_STORAGE_H