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_CORE_TO_INT16_H
9 #define LIBSIMDPP_SIMDPP_CORE_TO_INT16_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/detail/insn/conv_extend_to_int16.h>
17 #include <simdpp/detail/insn/conv_shrink_to_int16.h>
18 #include <simdpp/detail/insn/conv_float_to_int16.h>
19
20 namespace simdpp {
21 namespace SIMDPP_ARCH_NAMESPACE {
22
23
24 /** Converts elements within a vector to 16-bit signed values.
25
26 The conversion rules are as follows:
27 8-bit signed integers are sign-extended to 16 bits.
28 8-bit unsigned integers are zero-extended to 16 bits.
29 32-bit and wider integers are truncated.
30 floating-point numbers are converted to integer values and truncated.
31 If floating-point value can not be represented in 16-bit signed integer,
32 the behavior is different for different instruction sets.
33
34 @code
35 r0 = (int16_t) a0
36 ...
37 rN = (int16_t) aN
38 @endcode
39 */
40 template<unsigned N, class E> SIMDPP_INL
to_int16(const int8<N,E> & a)41 int16<N,expr_empty> to_int16(const int8<N,E>& a)
42 {
43 return detail::insn::i_to_int16(a.eval());
44 }
45 template<unsigned N, class E> SIMDPP_INL
to_int16(const uint8<N,E> & a)46 int16<N,expr_empty> to_int16(const uint8<N,E>& a)
47 {
48 return (int16<N>) detail::insn::i_to_uint16(a.eval());
49 }
50 template<unsigned N, class E> SIMDPP_INL
to_int16(const int16<N,E> & a)51 int16<N,expr_empty> to_int16(const int16<N,E>& a)
52 {
53 return a.eval();
54 }
55 template<unsigned N, class E> SIMDPP_INL
to_int16(const uint16<N,E> & a)56 int16<N,expr_empty> to_int16(const uint16<N,E>& a)
57 {
58 return int16<N>(a.eval());
59 }
60 template<unsigned N, class E> SIMDPP_INL
to_int16(const int32<N,E> & a)61 int16<N,expr_empty> to_int16(const int32<N,E>& a)
62 {
63 return detail::insn::i_to_uint16(uint32<N>(a.eval()));
64 }
65 template<unsigned N, class E> SIMDPP_INL
to_int16(const uint32<N,E> & a)66 int16<N,expr_empty> to_int16(const uint32<N,E>& a)
67 {
68 return detail::insn::i_to_uint16(a.eval());
69 }
70 template<unsigned N, class E> SIMDPP_INL
to_int16(const int64<N,E> & a)71 int16<N,expr_empty> to_int16(const int64<N,E>& a)
72 {
73 return detail::insn::i_to_uint16(uint64<N>(a.eval()));
74 }
75 template<unsigned N, class E> SIMDPP_INL
to_int16(const uint64<N,E> & a)76 int16<N,expr_empty> to_int16(const uint64<N,E>& a)
77 {
78 return detail::insn::i_to_uint16(a.eval());
79 }
80 template<unsigned N, class E> SIMDPP_INL
to_int16(const float32<N,E> & a)81 int16<N,expr_empty> to_int16(const float32<N,E>& a)
82 {
83 return detail::insn::i_to_int16(a.eval());
84 }
85 template<unsigned N, class E> SIMDPP_INL
to_int16(const float64<N,E> & a)86 int16<N,expr_empty> to_int16(const float64<N,E>& a)
87 {
88 return detail::insn::i_to_int16(a.eval());
89 }
90
91 /** Converts elements within a vector to 16-bit unsigned values.
92
93 The conversion rules are as follows:
94 8-bit signed integers are sign-extended to 16 bits.
95 8-bit unsigned integers are zero-extended to 16 bits.
96 32-bit and wider integers are truncated.
97 If floating-point value can not be represented in 16-bit unsigned integer,
98 the behavior is different for different instruction sets.
99
100 @code
101 r0 = (uint16_t) a0
102 ...
103 rN = (uint16_t) aN
104 @endcode
105 */
106 template<unsigned N, class E> SIMDPP_INL
to_uint16(const int8<N,E> & a)107 uint16<N,expr_empty> to_uint16(const int8<N,E>& a)
108 {
109 return (uint16<N>) detail::insn::i_to_int16(a.eval());
110 }
111 template<unsigned N, class E> SIMDPP_INL
to_uint16(const uint8<N,E> & a)112 uint16<N,expr_empty> to_uint16(const uint8<N,E>& a)
113 {
114 return detail::insn::i_to_uint16(a.eval());
115 }
116 template<unsigned N, class E> SIMDPP_INL
to_uint16(const int16<N,E> & a)117 uint16<N,expr_empty> to_uint16(const int16<N,E>& a)
118 {
119 return uint16<N>(a.eval());
120 }
121 template<unsigned N, class E> SIMDPP_INL
to_uint16(const uint16<N,E> & a)122 uint16<N,expr_empty> to_uint16(const uint16<N,E>& a)
123 {
124 return a.eval();
125 }
126 template<unsigned N, class E> SIMDPP_INL
to_uint16(const int32<N,E> & a)127 uint16<N,expr_empty> to_uint16(const int32<N,E>& a)
128 {
129 return detail::insn::i_to_uint16(uint32<N>(a.eval()));
130 }
131 template<unsigned N, class E> SIMDPP_INL
to_uint16(const uint32<N,E> & a)132 uint16<N,expr_empty> to_uint16(const uint32<N,E>& a)
133 {
134 return detail::insn::i_to_uint16(a.eval());
135 }
136 template<unsigned N, class E> SIMDPP_INL
to_uint16(const int64<N,E> & a)137 uint16<N,expr_empty> to_uint16(const int64<N,E>& a)
138 {
139 return detail::insn::i_to_uint16(uint64<N>(a.eval()));
140 }
141 template<unsigned N, class E> SIMDPP_INL
to_uint16(const uint64<N,E> & a)142 uint16<N,expr_empty> to_uint16(const uint64<N,E>& a)
143 {
144 return detail::insn::i_to_uint16(a.eval());
145 }
146 template<unsigned N, class E> SIMDPP_INL
to_uint16(const float32<N,E> & a)147 uint16<N,expr_empty> to_uint16(const float32<N,E>& a)
148 {
149 return detail::insn::i_to_uint16(a.eval());
150 }
151 template<unsigned N, class E> SIMDPP_INL
to_uint16(const float64<N,E> & a)152 uint16<N,expr_empty> to_uint16(const float64<N,E>& a)
153 {
154 return detail::insn::i_to_uint16(a.eval());
155 }
156
157 } // namespace SIMDPP_ARCH_NAMESPACE
158 } // namespace simdpp
159
160 #endif
161
162