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
21namespace simdpp {
22namespace SIMDPP_ARCH_NAMESPACE {
23namespace 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*/
30template<class V>
31class mem_block {
32public:
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_; }
50private:
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