1/* Copyright (C) 2014 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_CORE_DETAIL_VEC_EXTRACT_H
9#define LIBSIMDPP_SIMDPP_CORE_DETAIL_VEC_EXTRACT_H
10
11#ifndef LIBSIMDPP_SIMD_H
12 #error "This file must be included through simd.h"
13#endif
14
15#include <simdpp/setup_arch.h>
16#include <simdpp/types.h>
17#include <simdpp/core/insert.h>
18#include <simdpp/core/extract.h>
19
20namespace simdpp {
21namespace SIMDPP_ARCH_NAMESPACE {
22namespace detail {
23
24template<class R, class V> SIMDPP_INL
25R subvec_extract_impl(const V& a, unsigned n)
26{
27 static_assert(R::length >= V::base_length, "Too small vector to extract");
28
29 R r;
30 for (unsigned i = 0; i < r.vec_length; ++i) {
31 r.vec(i) = a.vec(n*r.vec_length + i);
32 }
33 return r;
34
35}
36
37// extract a sub-vector consisting of [M*n .. M*(n+1)) elements
38template<unsigned M, unsigned N> SIMDPP_INL
39uint8<M> subvec_extract(const uint8<N>& a, unsigned n)
40{
41 return subvec_extract_impl<uint8<M>>(a, n);
42}
43
44template<unsigned M, unsigned N> SIMDPP_INL
45uint16<M> subvec_extract(const uint16<N>& a, unsigned n)
46{
47 return subvec_extract_impl<uint16<M>>(a, n);
48}
49
50template<unsigned M, unsigned N> SIMDPP_INL
51uint32<M> subvec_extract(const uint32<N>& a, unsigned n)
52{
53 return subvec_extract_impl<uint32<M>>(a, n);
54}
55
56template<unsigned M, unsigned N> SIMDPP_INL
57uint64<M> subvec_extract(const uint64<N>& a, unsigned n)
58{
59 return subvec_extract_impl<uint64<M>>(a, n);
60}
61
62template<unsigned M, unsigned N> SIMDPP_INL
63int8<M> subvec_extract(const int8<N>& a, unsigned n)
64{
65 return subvec_extract_impl<int8<M>>(a, n);
66}
67
68template<unsigned M, unsigned N> SIMDPP_INL
69int16<M> subvec_extract(const int16<N>& a, unsigned n)
70{
71 return subvec_extract_impl<int16<M>>(a, n);
72}
73
74template<unsigned M, unsigned N> SIMDPP_INL
75int32<M> subvec_extract(const int32<N>& a, unsigned n)
76{
77 return subvec_extract_impl<int32<M>>(a, n);
78}
79
80template<unsigned M, unsigned N> SIMDPP_INL
81int64<M> subvec_extract(const int64<N>& a, unsigned n)
82{
83 return subvec_extract_impl<int64<M>>(a, n);
84}
85
86template<unsigned M, unsigned N> SIMDPP_INL
87float32<M> subvec_extract(const float32<N>& a, unsigned n)
88{
89 return subvec_extract_impl<float32<M>>(a, n);
90}
91
92template<unsigned M, unsigned N> SIMDPP_INL
93float64<M> subvec_extract(const float64<N>& a, unsigned n)
94{
95 return subvec_extract_impl<float64<M>>(a, n);
96}
97
98
99} // namespace detail
100} // namespace SIMDPP_ARCH_NAMESPACE
101} // namespace simdpp
102
103#endif
104