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