1 | /* Copyright (C) 2013 Povilas Kanapickas <povilas@radix.lt> |
2 | |
3 | Distributed under the Boost Software License, Version 1.0. |
4 | (See accompanying file LICENSE_1_0.txt or copy at |
5 | http://www.boost.org/LICENSE_1_0.txt) |
6 | */ |
7 | |
8 | #ifndef LIBSIMDPP_SIMDPP_DETAIL_MEM_BLOCK_H |
9 | #define LIBSIMDPP_SIMDPP_DETAIL_MEM_BLOCK_H |
10 | |
11 | #ifndef LIBSIMDPP_SIMD_H |
12 | #error "This file must be included through simd.h" |
13 | #endif |
14 | |
15 | #include <simdpp/types.h> |
16 | #include <simdpp/types/traits.h> |
17 | #include <simdpp/core/store.h> |
18 | #include <simdpp/core/load.h> |
19 | #include <cstring> |
20 | |
21 | namespace simdpp { |
22 | namespace SIMDPP_ARCH_NAMESPACE { |
23 | namespace detail { |
24 | |
25 | /** A block of memory that stores a vector and allows access to its elements. |
26 | Data transfer is not explicit -- the compiler is allowed to optimize it |
27 | however it wants, failing back to storing and loading from memory, if |
28 | necessary. |
29 | */ |
30 | template<class V> |
31 | class mem_block { |
32 | public: |
33 | static_assert(is_vector<V>::value, "Non-vector types are not supported" ); |
34 | |
35 | using element_type = typename V::element_type; |
36 | static const unsigned length = V::length; |
37 | |
38 | SIMDPP_INL mem_block() = default; |
39 | SIMDPP_INL mem_block(const mem_block&) = default; |
40 | SIMDPP_INL mem_block(const V& v) { store(d_, v); } |
41 | |
42 | SIMDPP_INL mem_block& operator=(const V& v) { store(d_, v); return *this; } |
43 | |
44 | SIMDPP_INL operator V() const { V r = load(d_); return r; } |
45 | |
46 | SIMDPP_INL const element_type& operator[](unsigned id) const { return d_[id]; } |
47 | SIMDPP_INL element_type& operator[](unsigned id) { return d_[id]; } |
48 | |
49 | SIMDPP_INL const element_type* data() const { return d_; } |
50 | private: |
51 | #if SIMDPP_USE_NEON32 |
52 | // On NEON the stack and vector types are not themselves 16-byte aligned |
53 | SIMDPP_ALIGN(16) element_type d_[length]; |
54 | #else |
55 | union { |
56 | element_type d_[length]; |
57 | V align_; |
58 | }; |
59 | #endif |
60 | }; |
61 | |
62 | } // namespace detail |
63 | } // namespace SIMDPP_ARCH_NAMESPACE |
64 | } // namespace simdpp |
65 | |
66 | #endif |
67 | |
68 | |