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
20namespace simdpp {
21namespace 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*/
40template<unsigned N, class E> SIMDPP_INL
41int16<N,expr_empty> to_int16(const int8<N,E>& a)
42{
43 return detail::insn::i_to_int16(a.eval());
44}
45template<unsigned N, class E> SIMDPP_INL
46int16<N,expr_empty> to_int16(const uint8<N,E>& a)
47{
48 return (int16<N>) detail::insn::i_to_uint16(a.eval());
49}
50template<unsigned N, class E> SIMDPP_INL
51int16<N,expr_empty> to_int16(const int16<N,E>& a)
52{
53 return a.eval();
54}
55template<unsigned N, class E> SIMDPP_INL
56int16<N,expr_empty> to_int16(const uint16<N,E>& a)
57{
58 return int16<N>(a.eval());
59}
60template<unsigned N, class E> SIMDPP_INL
61int16<N,expr_empty> to_int16(const int32<N,E>& a)
62{
63 return detail::insn::i_to_uint16(uint32<N>(a.eval()));
64}
65template<unsigned N, class E> SIMDPP_INL
66int16<N,expr_empty> to_int16(const uint32<N,E>& a)
67{
68 return detail::insn::i_to_uint16(a.eval());
69}
70template<unsigned N, class E> SIMDPP_INL
71int16<N,expr_empty> to_int16(const int64<N,E>& a)
72{
73 return detail::insn::i_to_uint16(uint64<N>(a.eval()));
74}
75template<unsigned N, class E> SIMDPP_INL
76int16<N,expr_empty> to_int16(const uint64<N,E>& a)
77{
78 return detail::insn::i_to_uint16(a.eval());
79}
80template<unsigned N, class E> SIMDPP_INL
81int16<N,expr_empty> to_int16(const float32<N,E>& a)
82{
83 return detail::insn::i_to_int16(a.eval());
84}
85template<unsigned N, class E> SIMDPP_INL
86int16<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*/
106template<unsigned N, class E> SIMDPP_INL
107uint16<N,expr_empty> to_uint16(const int8<N,E>& a)
108{
109 return (uint16<N>) detail::insn::i_to_int16(a.eval());
110}
111template<unsigned N, class E> SIMDPP_INL
112uint16<N,expr_empty> to_uint16(const uint8<N,E>& a)
113{
114 return detail::insn::i_to_uint16(a.eval());
115}
116template<unsigned N, class E> SIMDPP_INL
117uint16<N,expr_empty> to_uint16(const int16<N,E>& a)
118{
119 return uint16<N>(a.eval());
120}
121template<unsigned N, class E> SIMDPP_INL
122uint16<N,expr_empty> to_uint16(const uint16<N,E>& a)
123{
124 return a.eval();
125}
126template<unsigned N, class E> SIMDPP_INL
127uint16<N,expr_empty> to_uint16(const int32<N,E>& a)
128{
129 return detail::insn::i_to_uint16(uint32<N>(a.eval()));
130}
131template<unsigned N, class E> SIMDPP_INL
132uint16<N,expr_empty> to_uint16(const uint32<N,E>& a)
133{
134 return detail::insn::i_to_uint16(a.eval());
135}
136template<unsigned N, class E> SIMDPP_INL
137uint16<N,expr_empty> to_uint16(const int64<N,E>& a)
138{
139 return detail::insn::i_to_uint16(uint64<N>(a.eval()));
140}
141template<unsigned N, class E> SIMDPP_INL
142uint16<N,expr_empty> to_uint16(const uint64<N,E>& a)
143{
144 return detail::insn::i_to_uint16(a.eval());
145}
146template<unsigned N, class E> SIMDPP_INL
147uint16<N,expr_empty> to_uint16(const float32<N,E>& a)
148{
149 return detail::insn::i_to_uint16(a.eval());
150}
151template<unsigned N, class E> SIMDPP_INL
152uint16<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