| 1 | /*  Copyright (C) 2013-2017 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_INSN_DETAIL_CAST_INL | 
| 9 | #define LIBSIMDPP_SIMDPP_DETAIL_INSN_DETAIL_CAST_INL | 
| 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/detail/cast.h> | 
| 17 | #include <simdpp/detail/cast_bitwise.h> | 
| 18 | #include <simdpp/core/to_mask.h> | 
| 19 |  | 
| 20 | namespace simdpp { | 
| 21 | namespace SIMDPP_ARCH_NAMESPACE { | 
| 22 | namespace detail { | 
| 23 |  | 
| 24 | template<class T> struct base_mask_vector_type { using type = T; }; | 
| 25 | template<unsigned N> struct base_mask_vector_type<mask_int8<N>> { using type = uint8<N>; }; | 
| 26 | template<unsigned N> struct base_mask_vector_type<mask_int16<N>> { using type = uint16<N>; }; | 
| 27 | template<unsigned N> struct base_mask_vector_type<mask_int32<N>> { using type = uint32<N>; }; | 
| 28 | template<unsigned N> struct base_mask_vector_type<mask_int64<N>> { using type = uint64<N>; }; | 
| 29 | template<unsigned N> struct base_mask_vector_type<mask_float32<N>> { using type = float32<N>; }; | 
| 30 | template<unsigned N> struct base_mask_vector_type<mask_float64<N>> { using type = float64<N>; }; | 
| 31 |  | 
| 32 | template<class T, class R> SIMDPP_INL | 
| 33 | void cast_bitwise_unmask(const T& t, R& r) | 
| 34 | { | 
| 35 |     using TT = typename base_mask_vector_type<T>::type; | 
| 36 |     TT tt = t.unmask(); | 
| 37 |     cast_bitwise_vector(tt, r); | 
| 38 | } | 
| 39 |  | 
| 40 | template<class T, class R> SIMDPP_INL | 
| 41 | void cast_bitwise_remask(const T& t, R& r) | 
| 42 | { | 
| 43 |     using BaseMaskVector = typename base_mask_vector_type<R>::type; | 
| 44 |     BaseMaskVector rr; | 
| 45 |     cast_bitwise_vector(t.unmask(), rr); | 
| 46 |     r = to_mask(rr); | 
| 47 | } | 
| 48 |  | 
| 49 | template<> | 
| 50 | struct cast_wrapper<CAST_TYPE_OTHER> { | 
| 51 |     template<class T, class R> SIMDPP_INL | 
| 52 |     static void run(const T& t, R& r) | 
| 53 |     { | 
| 54 |         cast_bitwise(t, r); | 
| 55 |     } | 
| 56 | }; | 
| 57 |  | 
| 58 | template<> | 
| 59 | struct cast_wrapper<CAST_TYPE_MASK_TO_MASK_BITWISE> { | 
| 60 |     template<class T, class R> SIMDPP_INL | 
| 61 |     static void run(const T& t, R& r) | 
| 62 |     { | 
| 63 |         static_assert(R::size_tag == T::size_tag, | 
| 64 |                       "Conversions between masks with different element size is"  | 
| 65 |                       " not allowed" ); | 
| 66 |         cast_bitwise_vector(t.eval(), r); | 
| 67 |     } | 
| 68 | }; | 
| 69 |  | 
| 70 | template<> | 
| 71 | struct cast_wrapper<CAST_TYPE_MASK_TO_MASK_UNMASK> { | 
| 72 |     template<class R, class T> SIMDPP_INL | 
| 73 |     static void run(const T& t, R& r) | 
| 74 |     { | 
| 75 |         static_assert(R::size_tag == T::size_tag, | 
| 76 |                       "Conversions between masks with different element size is"  | 
| 77 |                       " not allowed" ); | 
| 78 |         cast_bitwise_unmask(t.eval(), r); | 
| 79 |     } | 
| 80 | }; | 
| 81 |  | 
| 82 | template<> | 
| 83 | struct cast_wrapper<CAST_TYPE_MASK_TO_MASK_REMASK> { | 
| 84 |     template<class R, class T> SIMDPP_INL | 
| 85 |     static void run(const T& t, R& r) | 
| 86 |     { | 
| 87 |         static_assert(R::size_tag == T::size_tag, | 
| 88 |                       "Conversions between masks with different element size is"  | 
| 89 |                       " not allowed" ); | 
| 90 |         cast_bitwise_remask(t.eval(), r); | 
| 91 |     } | 
| 92 | }; | 
| 93 |  | 
| 94 | template<> | 
| 95 | struct cast_wrapper<CAST_TYPE_VECTOR_TO_MASK> { | 
| 96 |     template<class R, class T> SIMDPP_INL | 
| 97 |     static void run(const T& t, R& r) | 
| 98 |     { | 
| 99 |         (void) t; (void) r; | 
| 100 |         static_assert(!std::is_same<T,T>::value, // fake dependency | 
| 101 |                       "Conversion from non-mask type to a mask type is not allowed" ); | 
| 102 |     } | 
| 103 | }; | 
| 104 |  | 
| 105 | template<> | 
| 106 | struct cast_wrapper<CAST_TYPE_MASK_TO_VECTOR> { | 
| 107 |     template<class R, class T> SIMDPP_INL | 
| 108 |     static void run(const T& t, R& r) | 
| 109 |     { | 
| 110 |         cast_bitwise_unmask(t.eval(), r); | 
| 111 |     } | 
| 112 | }; | 
| 113 |  | 
| 114 | template<> | 
| 115 | struct cast_wrapper<CAST_TYPE_VECTOR_TO_VECTOR> { | 
| 116 |     template<class R, class T> SIMDPP_INL | 
| 117 |     static void run(const T& t, R& r) | 
| 118 |     { | 
| 119 |         cast_bitwise_vector(t.eval(), r); | 
| 120 |     } | 
| 121 | }; | 
| 122 |  | 
| 123 | } // namespace detail | 
| 124 | } // namespace SIMDPP_ARCH_NAMESPACE | 
| 125 | } // namespace simdpp | 
| 126 |  | 
| 127 | #endif | 
| 128 |  | 
| 129 |  |