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;
mem_block(const V & v)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 
V()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 
data()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