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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 | |