]> git.uio.no Git - u/mrichter/AliRoot.git/blame - Vc/include/Vc/common/storage.h
update to Vc 0.7.3-dev
[u/mrichter/AliRoot.git] / Vc / include / Vc / common / storage.h
CommitLineData
f22341db 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"
c017a39f 25#include "types.h"
f22341db 26
c017a39f 27namespace AliRoot {
f22341db 28namespace Vc
29{
30namespace Common
31{
32
c017a39f 33template<typename _VectorType, typename _EntryType, typename VectorTypeBase = _VectorType> class VectorMemoryUnion
f22341db 34{
35 public:
36 typedef _VectorType VectorType;
37 typedef _EntryType EntryType;
c017a39f 38 typedef EntryType AliasingEntryType Vc_MAY_ALIAS;
39 Vc_ALWAYS_INLINE VectorMemoryUnion() { assertCorrectAlignment(&v()); }
f22341db 40#if defined VC_ICC || defined VC_MSVC
c017a39f 41 Vc_ALWAYS_INLINE VectorMemoryUnion(const VectorType &x) { data.v = x; assertCorrectAlignment(&data.v); }
42 Vc_ALWAYS_INLINE VectorMemoryUnion &operator=(const VectorType &x) {
f22341db 43 data.v = x; return *this;
44 }
45
c017a39f 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); }
f22341db 48
49#if defined VC_ICC
c017a39f 50 Vc_ALWAYS_INLINE Vc_PURE AliasingEntryHelper<VectorMemoryUnion> m(size_t index) {
51 return AliasingEntryHelper<VectorMemoryUnion>(this, index);
f22341db 52 }
c017a39f 53 Vc_ALWAYS_INLINE void assign(size_t index, EntryType x) {
f22341db 54 data.m[index] = x;
55 }
c017a39f 56 Vc_ALWAYS_INLINE Vc_PURE EntryType read(size_t index) const {
f22341db 57 return data.m[index];
58 }
59#else
c017a39f 60 Vc_ALWAYS_INLINE Vc_PURE EntryType &m(size_t index) {
f22341db 61 return data.m[index];
62 }
63#endif
64
c017a39f 65 Vc_ALWAYS_INLINE Vc_PURE EntryType m(size_t index) const {
f22341db 66 return data.m[index];
67 }
68
c017a39f 69#ifdef VC_COMPILE_BENCHMARKS
70 public:
71#endif
f22341db 72 private:
73 union VectorScalarUnion {
c017a39f 74 VectorTypeBase v;
75 EntryType m[sizeof(VectorTypeBase)/sizeof(EntryType)];
f22341db 76 } data;
77#else
c017a39f 78 Vc_ALWAYS_INLINE VectorMemoryUnion(VectorType x) : data(x) { assertCorrectAlignment(&data); }
79 Vc_ALWAYS_INLINE VectorMemoryUnion &operator=(VectorType x) {
f22341db 80 data = x; return *this;
81 }
82
c017a39f 83 Vc_ALWAYS_INLINE Vc_PURE VectorType &v() { return data; }
84 Vc_ALWAYS_INLINE Vc_PURE const VectorType &v() const { return data; }
f22341db 85
c017a39f 86 Vc_ALWAYS_INLINE Vc_PURE AliasingEntryType &m(size_t index) {
f22341db 87 return reinterpret_cast<AliasingEntryType *>(&data)[index];
88 }
89
c017a39f 90 Vc_ALWAYS_INLINE Vc_PURE EntryType m(size_t index) const {
f22341db 91 return reinterpret_cast<const AliasingEntryType *>(&data)[index];
92 }
93
94 private:
c017a39f 95#ifdef VC_COMPILE_BENCHMARKS
96 public:
97#endif
f22341db 98 VectorType data;
99#endif
100};
101
102#if VC_GCC == 0x40700 || (VC_GCC >= 0x40600 && VC_GCC <= 0x40603)
103// workaround bug 52736 in GCC
c017a39f 104template<typename T, typename V> static Vc_ALWAYS_INLINE Vc_CONST T &vectorMemoryUnionAliasedMember(V *data, size_t index) {
f22341db 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}
c017a39f 113template<> Vc_ALWAYS_INLINE Vc_PURE VectorMemoryUnion<__m128d, double>::AliasingEntryType &VectorMemoryUnion<__m128d, double>::m(size_t index) {
f22341db 114 return vectorMemoryUnionAliasedMember<AliasingEntryType>(&data, index);
115}
c017a39f 116template<> Vc_ALWAYS_INLINE Vc_PURE VectorMemoryUnion<__m128i, long long>::AliasingEntryType &VectorMemoryUnion<__m128i, long long>::m(size_t index) {
f22341db 117 return vectorMemoryUnionAliasedMember<AliasingEntryType>(&data, index);
118}
c017a39f 119template<> Vc_ALWAYS_INLINE Vc_PURE VectorMemoryUnion<__m128i, unsigned long long>::AliasingEntryType &VectorMemoryUnion<__m128i, unsigned long long>::m(size_t index) {
f22341db 120 return vectorMemoryUnionAliasedMember<AliasingEntryType>(&data, index);
121}
122#endif
123
124} // namespace Common
125} // namespace Vc
c017a39f 126} // namespace AliRoot
f22341db 127
128#include "undomacros.h"
129
130#endif // VC_COMMON_STORAGE_H