1*35ffd701SAndroid Build Coastguard Worker #ifndef SSE2NEON_H
2*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_H
3*35ffd701SAndroid Build Coastguard Worker
4*35ffd701SAndroid Build Coastguard Worker // This header file provides a simple API translation layer
5*35ffd701SAndroid Build Coastguard Worker // between SSE intrinsics to their corresponding Arm/Aarch64 NEON versions
6*35ffd701SAndroid Build Coastguard Worker //
7*35ffd701SAndroid Build Coastguard Worker // This header file does not yet translate all of the SSE intrinsics.
8*35ffd701SAndroid Build Coastguard Worker //
9*35ffd701SAndroid Build Coastguard Worker // Contributors to this work are:
10*35ffd701SAndroid Build Coastguard Worker // John W. Ratcliff <[email protected]>
11*35ffd701SAndroid Build Coastguard Worker // Brandon Rowlett <[email protected]>
12*35ffd701SAndroid Build Coastguard Worker // Ken Fast <[email protected]>
13*35ffd701SAndroid Build Coastguard Worker // Eric van Beurden <[email protected]>
14*35ffd701SAndroid Build Coastguard Worker // Alexander Potylitsin <[email protected]>
15*35ffd701SAndroid Build Coastguard Worker // Hasindu Gamaarachchi <[email protected]>
16*35ffd701SAndroid Build Coastguard Worker // Jim Huang <[email protected]>
17*35ffd701SAndroid Build Coastguard Worker // Mark Cheng <[email protected]>
18*35ffd701SAndroid Build Coastguard Worker // Malcolm James MacLeod <[email protected]>
19*35ffd701SAndroid Build Coastguard Worker // Devin Hussey (easyaspi314) <[email protected]>
20*35ffd701SAndroid Build Coastguard Worker // Sebastian Pop <[email protected]>
21*35ffd701SAndroid Build Coastguard Worker // Developer Ecosystem Engineering <[email protected]>
22*35ffd701SAndroid Build Coastguard Worker // Danila Kutenin <[email protected]>
23*35ffd701SAndroid Build Coastguard Worker // François Turban (JishinMaster) <[email protected]>
24*35ffd701SAndroid Build Coastguard Worker // Pei-Hsuan Hung <[email protected]>
25*35ffd701SAndroid Build Coastguard Worker // Yang-Hao Yuan <[email protected]>
26*35ffd701SAndroid Build Coastguard Worker // Syoyo Fujita <[email protected]>
27*35ffd701SAndroid Build Coastguard Worker // Brecht Van Lommel <[email protected]>
28*35ffd701SAndroid Build Coastguard Worker
29*35ffd701SAndroid Build Coastguard Worker /*
30*35ffd701SAndroid Build Coastguard Worker * sse2neon is freely redistributable under the MIT License.
31*35ffd701SAndroid Build Coastguard Worker *
32*35ffd701SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
33*35ffd701SAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to deal
34*35ffd701SAndroid Build Coastguard Worker * in the Software without restriction, including without limitation the rights
35*35ffd701SAndroid Build Coastguard Worker * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36*35ffd701SAndroid Build Coastguard Worker * copies of the Software, and to permit persons to whom the Software is
37*35ffd701SAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
38*35ffd701SAndroid Build Coastguard Worker *
39*35ffd701SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in
40*35ffd701SAndroid Build Coastguard Worker * all copies or substantial portions of the Software.
41*35ffd701SAndroid Build Coastguard Worker *
42*35ffd701SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43*35ffd701SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44*35ffd701SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45*35ffd701SAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46*35ffd701SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47*35ffd701SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
48*35ffd701SAndroid Build Coastguard Worker * SOFTWARE.
49*35ffd701SAndroid Build Coastguard Worker */
50*35ffd701SAndroid Build Coastguard Worker
51*35ffd701SAndroid Build Coastguard Worker /* Tunable configurations */
52*35ffd701SAndroid Build Coastguard Worker
53*35ffd701SAndroid Build Coastguard Worker /* Enable precise implementation of math operations
54*35ffd701SAndroid Build Coastguard Worker * This would slow down the computation a bit, but gives consistent result with
55*35ffd701SAndroid Build Coastguard Worker * x86 SSE2. (e.g. would solve a hole or NaN pixel in the rendering result)
56*35ffd701SAndroid Build Coastguard Worker */
57*35ffd701SAndroid Build Coastguard Worker /* _mm_min_ps and _mm_max_ps */
58*35ffd701SAndroid Build Coastguard Worker #ifndef SSE2NEON_PRECISE_MINMAX
59*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_PRECISE_MINMAX (0)
60*35ffd701SAndroid Build Coastguard Worker #endif
61*35ffd701SAndroid Build Coastguard Worker /* _mm_rcp_ps and _mm_div_ps */
62*35ffd701SAndroid Build Coastguard Worker #ifndef SSE2NEON_PRECISE_DIV
63*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_PRECISE_DIV (0)
64*35ffd701SAndroid Build Coastguard Worker #endif
65*35ffd701SAndroid Build Coastguard Worker /* _mm_sqrt_ps and _mm_rsqrt_ps */
66*35ffd701SAndroid Build Coastguard Worker #ifndef SSE2NEON_PRECISE_SQRT
67*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_PRECISE_SQRT (0)
68*35ffd701SAndroid Build Coastguard Worker #endif
69*35ffd701SAndroid Build Coastguard Worker
70*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
71*35ffd701SAndroid Build Coastguard Worker #pragma push_macro("FORCE_INLINE")
72*35ffd701SAndroid Build Coastguard Worker #pragma push_macro("ALIGN_STRUCT")
73*35ffd701SAndroid Build Coastguard Worker #define FORCE_INLINE static inline __attribute__((always_inline))
74*35ffd701SAndroid Build Coastguard Worker #define ALIGN_STRUCT(x) __attribute__((aligned(x)))
75*35ffd701SAndroid Build Coastguard Worker #ifndef likely
76*35ffd701SAndroid Build Coastguard Worker #define likely(x) __builtin_expect(!!(x), 1)
77*35ffd701SAndroid Build Coastguard Worker #endif
78*35ffd701SAndroid Build Coastguard Worker #ifndef unlikely
79*35ffd701SAndroid Build Coastguard Worker #define unlikely(x) __builtin_expect(!!(x), 0)
80*35ffd701SAndroid Build Coastguard Worker #endif
81*35ffd701SAndroid Build Coastguard Worker #else
82*35ffd701SAndroid Build Coastguard Worker #error "Macro name collisions may happen with unsupported compiler."
83*35ffd701SAndroid Build Coastguard Worker #ifdef FORCE_INLINE
84*35ffd701SAndroid Build Coastguard Worker #undef FORCE_INLINE
85*35ffd701SAndroid Build Coastguard Worker #endif
86*35ffd701SAndroid Build Coastguard Worker #define FORCE_INLINE static inline
87*35ffd701SAndroid Build Coastguard Worker #ifndef ALIGN_STRUCT
88*35ffd701SAndroid Build Coastguard Worker #define ALIGN_STRUCT(x) __declspec(align(x))
89*35ffd701SAndroid Build Coastguard Worker #endif
90*35ffd701SAndroid Build Coastguard Worker #endif
91*35ffd701SAndroid Build Coastguard Worker #ifndef likely
92*35ffd701SAndroid Build Coastguard Worker #define likely(x) (x)
93*35ffd701SAndroid Build Coastguard Worker #endif
94*35ffd701SAndroid Build Coastguard Worker #ifndef unlikely
95*35ffd701SAndroid Build Coastguard Worker #define unlikely(x) (x)
96*35ffd701SAndroid Build Coastguard Worker #endif
97*35ffd701SAndroid Build Coastguard Worker
98*35ffd701SAndroid Build Coastguard Worker #include <stdint.h>
99*35ffd701SAndroid Build Coastguard Worker #include <stdlib.h>
100*35ffd701SAndroid Build Coastguard Worker
101*35ffd701SAndroid Build Coastguard Worker /* Architecture-specific build options */
102*35ffd701SAndroid Build Coastguard Worker /* FIXME: #pragma GCC push_options is only available on GCC */
103*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__)
104*35ffd701SAndroid Build Coastguard Worker #if defined(__arm__) && __ARM_ARCH == 7
105*35ffd701SAndroid Build Coastguard Worker /* According to ARM C Language Extensions Architecture specification,
106*35ffd701SAndroid Build Coastguard Worker * __ARM_NEON is defined to a value indicating the Advanced SIMD (NEON)
107*35ffd701SAndroid Build Coastguard Worker * architecture supported.
108*35ffd701SAndroid Build Coastguard Worker */
109*35ffd701SAndroid Build Coastguard Worker #if !defined(__ARM_NEON) || !defined(__ARM_NEON__)
110*35ffd701SAndroid Build Coastguard Worker #error "You must enable NEON instructions (e.g. -mfpu=neon) to use SSE2NEON."
111*35ffd701SAndroid Build Coastguard Worker #endif
112*35ffd701SAndroid Build Coastguard Worker #if !defined(__clang__)
113*35ffd701SAndroid Build Coastguard Worker #pragma GCC push_options
114*35ffd701SAndroid Build Coastguard Worker #pragma GCC target("fpu=neon")
115*35ffd701SAndroid Build Coastguard Worker #endif
116*35ffd701SAndroid Build Coastguard Worker #elif defined(__aarch64__)
117*35ffd701SAndroid Build Coastguard Worker #if !defined(__clang__)
118*35ffd701SAndroid Build Coastguard Worker #pragma GCC push_options
119*35ffd701SAndroid Build Coastguard Worker #pragma GCC target("+simd")
120*35ffd701SAndroid Build Coastguard Worker #endif
121*35ffd701SAndroid Build Coastguard Worker #else
122*35ffd701SAndroid Build Coastguard Worker #error "Unsupported target. Must be either ARMv7-A+NEON or ARMv8-A."
123*35ffd701SAndroid Build Coastguard Worker #endif
124*35ffd701SAndroid Build Coastguard Worker #endif
125*35ffd701SAndroid Build Coastguard Worker
126*35ffd701SAndroid Build Coastguard Worker #include <arm_neon.h>
127*35ffd701SAndroid Build Coastguard Worker
128*35ffd701SAndroid Build Coastguard Worker /* Rounding functions require either Aarch64 instructions or libm failback */
129*35ffd701SAndroid Build Coastguard Worker #if !defined(__aarch64__)
130*35ffd701SAndroid Build Coastguard Worker #include <math.h>
131*35ffd701SAndroid Build Coastguard Worker #endif
132*35ffd701SAndroid Build Coastguard Worker
133*35ffd701SAndroid Build Coastguard Worker /* "__has_builtin" can be used to query support for built-in functions
134*35ffd701SAndroid Build Coastguard Worker * provided by gcc/clang and other compilers that support it.
135*35ffd701SAndroid Build Coastguard Worker */
136*35ffd701SAndroid Build Coastguard Worker #ifndef __has_builtin /* GCC prior to 10 or non-clang compilers */
137*35ffd701SAndroid Build Coastguard Worker /* Compatibility with gcc <= 9 */
138*35ffd701SAndroid Build Coastguard Worker #if __GNUC__ <= 9
139*35ffd701SAndroid Build Coastguard Worker #define __has_builtin(x) HAS##x
140*35ffd701SAndroid Build Coastguard Worker #define HAS__builtin_popcount 1
141*35ffd701SAndroid Build Coastguard Worker #define HAS__builtin_popcountll 1
142*35ffd701SAndroid Build Coastguard Worker #else
143*35ffd701SAndroid Build Coastguard Worker #define __has_builtin(x) 0
144*35ffd701SAndroid Build Coastguard Worker #endif
145*35ffd701SAndroid Build Coastguard Worker #endif
146*35ffd701SAndroid Build Coastguard Worker
147*35ffd701SAndroid Build Coastguard Worker /**
148*35ffd701SAndroid Build Coastguard Worker * MACRO for shuffle parameter for _mm_shuffle_ps().
149*35ffd701SAndroid Build Coastguard Worker * Argument fp3 is a digit[0123] that represents the fp from argument "b"
150*35ffd701SAndroid Build Coastguard Worker * of mm_shuffle_ps that will be placed in fp3 of result. fp2 is the same
151*35ffd701SAndroid Build Coastguard Worker * for fp2 in result. fp1 is a digit[0123] that represents the fp from
152*35ffd701SAndroid Build Coastguard Worker * argument "a" of mm_shuffle_ps that will be places in fp1 of result.
153*35ffd701SAndroid Build Coastguard Worker * fp0 is the same for fp0 of result.
154*35ffd701SAndroid Build Coastguard Worker */
155*35ffd701SAndroid Build Coastguard Worker #define _MM_SHUFFLE(fp3, fp2, fp1, fp0) \
156*35ffd701SAndroid Build Coastguard Worker (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | ((fp0)))
157*35ffd701SAndroid Build Coastguard Worker
158*35ffd701SAndroid Build Coastguard Worker /* Rounding mode macros. */
159*35ffd701SAndroid Build Coastguard Worker #define _MM_FROUND_TO_NEAREST_INT 0x00
160*35ffd701SAndroid Build Coastguard Worker #define _MM_FROUND_TO_NEG_INF 0x01
161*35ffd701SAndroid Build Coastguard Worker #define _MM_FROUND_TO_POS_INF 0x02
162*35ffd701SAndroid Build Coastguard Worker #define _MM_FROUND_TO_ZERO 0x03
163*35ffd701SAndroid Build Coastguard Worker #define _MM_FROUND_CUR_DIRECTION 0x04
164*35ffd701SAndroid Build Coastguard Worker #define _MM_FROUND_NO_EXC 0x08
165*35ffd701SAndroid Build Coastguard Worker #define _MM_ROUND_NEAREST 0x0000
166*35ffd701SAndroid Build Coastguard Worker #define _MM_ROUND_DOWN 0x2000
167*35ffd701SAndroid Build Coastguard Worker #define _MM_ROUND_UP 0x4000
168*35ffd701SAndroid Build Coastguard Worker #define _MM_ROUND_TOWARD_ZERO 0x6000
169*35ffd701SAndroid Build Coastguard Worker
170*35ffd701SAndroid Build Coastguard Worker /* indicate immediate constant argument in a given range */
171*35ffd701SAndroid Build Coastguard Worker #define __constrange(a, b) const
172*35ffd701SAndroid Build Coastguard Worker
173*35ffd701SAndroid Build Coastguard Worker /* A few intrinsics accept traditional data types like ints or floats, but
174*35ffd701SAndroid Build Coastguard Worker * most operate on data types that are specific to SSE.
175*35ffd701SAndroid Build Coastguard Worker * If a vector type ends in d, it contains doubles, and if it does not have
176*35ffd701SAndroid Build Coastguard Worker * a suffix, it contains floats. An integer vector type can contain any type
177*35ffd701SAndroid Build Coastguard Worker * of integer, from chars to shorts to unsigned long longs.
178*35ffd701SAndroid Build Coastguard Worker */
179*35ffd701SAndroid Build Coastguard Worker typedef int64x1_t __m64;
180*35ffd701SAndroid Build Coastguard Worker typedef float32x4_t __m128; /* 128-bit vector containing 4 floats */
181*35ffd701SAndroid Build Coastguard Worker // On ARM 32-bit architecture, the float64x2_t is not supported.
182*35ffd701SAndroid Build Coastguard Worker // The data type __m128d should be represented in a different way for related
183*35ffd701SAndroid Build Coastguard Worker // intrinsic conversion.
184*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
185*35ffd701SAndroid Build Coastguard Worker typedef float64x2_t __m128d; /* 128-bit vector containing 2 doubles */
186*35ffd701SAndroid Build Coastguard Worker #else
187*35ffd701SAndroid Build Coastguard Worker typedef float32x4_t __m128d;
188*35ffd701SAndroid Build Coastguard Worker #endif
189*35ffd701SAndroid Build Coastguard Worker typedef int64x2_t __m128i; /* 128-bit vector containing integers */
190*35ffd701SAndroid Build Coastguard Worker
191*35ffd701SAndroid Build Coastguard Worker /* type-safe casting between types */
192*35ffd701SAndroid Build Coastguard Worker
193*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_f16(x) vreinterpretq_f32_f16(x)
194*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_f32(x) (x)
195*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_f64(x) vreinterpretq_f32_f64(x)
196*35ffd701SAndroid Build Coastguard Worker
197*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_u8(x) vreinterpretq_f32_u8(x)
198*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_u16(x) vreinterpretq_f32_u16(x)
199*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_u32(x) vreinterpretq_f32_u32(x)
200*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_u64(x) vreinterpretq_f32_u64(x)
201*35ffd701SAndroid Build Coastguard Worker
202*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_s8(x) vreinterpretq_f32_s8(x)
203*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_s16(x) vreinterpretq_f32_s16(x)
204*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_s32(x) vreinterpretq_f32_s32(x)
205*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128_s64(x) vreinterpretq_f32_s64(x)
206*35ffd701SAndroid Build Coastguard Worker
207*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_f16_m128(x) vreinterpretq_f16_f32(x)
208*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_f32_m128(x) (x)
209*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_f64_m128(x) vreinterpretq_f64_f32(x)
210*35ffd701SAndroid Build Coastguard Worker
211*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u8_m128(x) vreinterpretq_u8_f32(x)
212*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u16_m128(x) vreinterpretq_u16_f32(x)
213*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u32_m128(x) vreinterpretq_u32_f32(x)
214*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u64_m128(x) vreinterpretq_u64_f32(x)
215*35ffd701SAndroid Build Coastguard Worker
216*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s8_m128(x) vreinterpretq_s8_f32(x)
217*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s16_m128(x) vreinterpretq_s16_f32(x)
218*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s32_m128(x) vreinterpretq_s32_f32(x)
219*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s64_m128(x) vreinterpretq_s64_f32(x)
220*35ffd701SAndroid Build Coastguard Worker
221*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128i_s8(x) vreinterpretq_s64_s8(x)
222*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128i_s16(x) vreinterpretq_s64_s16(x)
223*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128i_s32(x) vreinterpretq_s64_s32(x)
224*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128i_s64(x) (x)
225*35ffd701SAndroid Build Coastguard Worker
226*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128i_u8(x) vreinterpretq_s64_u8(x)
227*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128i_u16(x) vreinterpretq_s64_u16(x)
228*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128i_u32(x) vreinterpretq_s64_u32(x)
229*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128i_u64(x) vreinterpretq_s64_u64(x)
230*35ffd701SAndroid Build Coastguard Worker
231*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_f32_m128i(x) vreinterpretq_f32_s64(x)
232*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_f64_m128i(x) vreinterpretq_f64_s64(x)
233*35ffd701SAndroid Build Coastguard Worker
234*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s8_m128i(x) vreinterpretq_s8_s64(x)
235*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s16_m128i(x) vreinterpretq_s16_s64(x)
236*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s32_m128i(x) vreinterpretq_s32_s64(x)
237*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s64_m128i(x) (x)
238*35ffd701SAndroid Build Coastguard Worker
239*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u8_m128i(x) vreinterpretq_u8_s64(x)
240*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u16_m128i(x) vreinterpretq_u16_s64(x)
241*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u32_m128i(x) vreinterpretq_u32_s64(x)
242*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u64_m128i(x) vreinterpretq_u64_s64(x)
243*35ffd701SAndroid Build Coastguard Worker
244*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_s8(x) vreinterpret_s64_s8(x)
245*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_s16(x) vreinterpret_s64_s16(x)
246*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_s32(x) vreinterpret_s64_s32(x)
247*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_s64(x) (x)
248*35ffd701SAndroid Build Coastguard Worker
249*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_u8(x) vreinterpret_s64_u8(x)
250*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_u16(x) vreinterpret_s64_u16(x)
251*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_u32(x) vreinterpret_s64_u32(x)
252*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_u64(x) vreinterpret_s64_u64(x)
253*35ffd701SAndroid Build Coastguard Worker
254*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_f16(x) vreinterpret_s64_f16(x)
255*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_f32(x) vreinterpret_s64_f32(x)
256*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_m64_f64(x) vreinterpret_s64_f64(x)
257*35ffd701SAndroid Build Coastguard Worker
258*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_u8_m64(x) vreinterpret_u8_s64(x)
259*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_u16_m64(x) vreinterpret_u16_s64(x)
260*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_u32_m64(x) vreinterpret_u32_s64(x)
261*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_u64_m64(x) vreinterpret_u64_s64(x)
262*35ffd701SAndroid Build Coastguard Worker
263*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_s8_m64(x) vreinterpret_s8_s64(x)
264*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_s16_m64(x) vreinterpret_s16_s64(x)
265*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_s32_m64(x) vreinterpret_s32_s64(x)
266*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_s64_m64(x) (x)
267*35ffd701SAndroid Build Coastguard Worker
268*35ffd701SAndroid Build Coastguard Worker #define vreinterpret_f32_m64(x) vreinterpret_f32_s64(x)
269*35ffd701SAndroid Build Coastguard Worker
270*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
271*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_s32(x) vreinterpretq_f64_s32(x)
272*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_s64(x) vreinterpretq_f64_s64(x)
273*35ffd701SAndroid Build Coastguard Worker
274*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_u64(x) vreinterpretq_f64_u64(x)
275*35ffd701SAndroid Build Coastguard Worker
276*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_f32(x) vreinterpretq_f64_f32(x)
277*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_f64(x) (x)
278*35ffd701SAndroid Build Coastguard Worker
279*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s64_m128d(x) vreinterpretq_s64_f64(x)
280*35ffd701SAndroid Build Coastguard Worker
281*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u32_m128d(x) vreinterpretq_u32_f64(x)
282*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u64_m128d(x) vreinterpretq_u64_f64(x)
283*35ffd701SAndroid Build Coastguard Worker
284*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_f64_m128d(x) (x)
285*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_f32_m128d(x) vreinterpretq_f32_f64(x)
286*35ffd701SAndroid Build Coastguard Worker #else
287*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_s32(x) vreinterpretq_f32_s32(x)
288*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_s64(x) vreinterpretq_f32_s64(x)
289*35ffd701SAndroid Build Coastguard Worker
290*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_u32(x) vreinterpretq_f32_u32(x)
291*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_u64(x) vreinterpretq_f32_u64(x)
292*35ffd701SAndroid Build Coastguard Worker
293*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_m128d_f32(x) (x)
294*35ffd701SAndroid Build Coastguard Worker
295*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_s64_m128d(x) vreinterpretq_s64_f32(x)
296*35ffd701SAndroid Build Coastguard Worker
297*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u32_m128d(x) vreinterpretq_u32_f32(x)
298*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_u64_m128d(x) vreinterpretq_u64_f32(x)
299*35ffd701SAndroid Build Coastguard Worker
300*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_f32_m128d(x) (x)
301*35ffd701SAndroid Build Coastguard Worker #endif
302*35ffd701SAndroid Build Coastguard Worker
303*35ffd701SAndroid Build Coastguard Worker // A struct is defined in this header file called 'SIMDVec' which can be used
304*35ffd701SAndroid Build Coastguard Worker // by applications which attempt to access the contents of an _m128 struct
305*35ffd701SAndroid Build Coastguard Worker // directly. It is important to note that accessing the __m128 struct directly
306*35ffd701SAndroid Build Coastguard Worker // is bad coding practice by Microsoft: @see:
307*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx
308*35ffd701SAndroid Build Coastguard Worker //
309*35ffd701SAndroid Build Coastguard Worker // However, some legacy source code may try to access the contents of an __m128
310*35ffd701SAndroid Build Coastguard Worker // struct directly so the developer can use the SIMDVec as an alias for it. Any
311*35ffd701SAndroid Build Coastguard Worker // casting must be done manually by the developer, as you cannot cast or
312*35ffd701SAndroid Build Coastguard Worker // otherwise alias the base NEON data type for intrinsic operations.
313*35ffd701SAndroid Build Coastguard Worker //
314*35ffd701SAndroid Build Coastguard Worker // union intended to allow direct access to an __m128 variable using the names
315*35ffd701SAndroid Build Coastguard Worker // that the MSVC compiler provides. This union should really only be used when
316*35ffd701SAndroid Build Coastguard Worker // trying to access the members of the vector as integer values. GCC/clang
317*35ffd701SAndroid Build Coastguard Worker // allow native access to the float members through a simple array access
318*35ffd701SAndroid Build Coastguard Worker // operator (in C since 4.6, in C++ since 4.8).
319*35ffd701SAndroid Build Coastguard Worker //
320*35ffd701SAndroid Build Coastguard Worker // Ideally direct accesses to SIMD vectors should not be used since it can cause
321*35ffd701SAndroid Build Coastguard Worker // a performance hit. If it really is needed however, the original __m128
322*35ffd701SAndroid Build Coastguard Worker // variable can be aliased with a pointer to this union and used to access
323*35ffd701SAndroid Build Coastguard Worker // individual components. The use of this union should be hidden behind a macro
324*35ffd701SAndroid Build Coastguard Worker // that is used throughout the codebase to access the members instead of always
325*35ffd701SAndroid Build Coastguard Worker // declaring this type of variable.
326*35ffd701SAndroid Build Coastguard Worker typedef union ALIGN_STRUCT(16) SIMDVec {
327*35ffd701SAndroid Build Coastguard Worker float m128_f32[4]; // as floats - DON'T USE. Added for convenience.
328*35ffd701SAndroid Build Coastguard Worker int8_t m128_i8[16]; // as signed 8-bit integers.
329*35ffd701SAndroid Build Coastguard Worker int16_t m128_i16[8]; // as signed 16-bit integers.
330*35ffd701SAndroid Build Coastguard Worker int32_t m128_i32[4]; // as signed 32-bit integers.
331*35ffd701SAndroid Build Coastguard Worker int64_t m128_i64[2]; // as signed 64-bit integers.
332*35ffd701SAndroid Build Coastguard Worker uint8_t m128_u8[16]; // as unsigned 8-bit integers.
333*35ffd701SAndroid Build Coastguard Worker uint16_t m128_u16[8]; // as unsigned 16-bit integers.
334*35ffd701SAndroid Build Coastguard Worker uint32_t m128_u32[4]; // as unsigned 32-bit integers.
335*35ffd701SAndroid Build Coastguard Worker uint64_t m128_u64[2]; // as unsigned 64-bit integers.
336*35ffd701SAndroid Build Coastguard Worker } SIMDVec;
337*35ffd701SAndroid Build Coastguard Worker
338*35ffd701SAndroid Build Coastguard Worker // casting using SIMDVec
339*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_nth_u64_m128i(x, n) (((SIMDVec *) &x)->m128_u64[n])
340*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_nth_u32_m128i(x, n) (((SIMDVec *) &x)->m128_u32[n])
341*35ffd701SAndroid Build Coastguard Worker #define vreinterpretq_nth_u8_m128i(x, n) (((SIMDVec *) &x)->m128_u8[n])
342*35ffd701SAndroid Build Coastguard Worker
343*35ffd701SAndroid Build Coastguard Worker // Function declaration
344*35ffd701SAndroid Build Coastguard Worker // SSE
345*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE();
346*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_move_ss(__m128, __m128);
347*35ffd701SAndroid Build Coastguard Worker // SSE2
348*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtps_epi32(__m128);
349*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_move_sd(__m128d, __m128d);
350*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set_epi32(int, int, int, int);
351*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set_epi64x(int64_t, int64_t);
352*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_set_pd(double, double);
353*35ffd701SAndroid Build Coastguard Worker // SSE4.1
354*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_ceil_pd(__m128d);
355*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_ceil_ps(__m128);
356*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_floor_pd(__m128d);
357*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_floor_ps(__m128);
358*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_round_pd(__m128d, int);
359*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_round_ps(__m128, int);
360*35ffd701SAndroid Build Coastguard Worker // SSE4.2
361*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t, uint8_t);
362*35ffd701SAndroid Build Coastguard Worker
363*35ffd701SAndroid Build Coastguard Worker /* Backwards compatibility for compilers with lack of specific type support */
364*35ffd701SAndroid Build Coastguard Worker
365*35ffd701SAndroid Build Coastguard Worker // Older gcc does not define vld1q_u8_x4 type
366*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__clang__) && \
367*35ffd701SAndroid Build Coastguard Worker ((__GNUC__ <= 10 && defined(__arm__)) || \
368*35ffd701SAndroid Build Coastguard Worker (__GNUC__ == 10 && __GNUC_MINOR__ < 3 && defined(__aarch64__)) || \
369*35ffd701SAndroid Build Coastguard Worker (__GNUC__ <= 9 && defined(__aarch64__)))
_sse2neon_vld1q_u8_x4(const uint8_t * p)370*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p)
371*35ffd701SAndroid Build Coastguard Worker {
372*35ffd701SAndroid Build Coastguard Worker uint8x16x4_t ret;
373*35ffd701SAndroid Build Coastguard Worker ret.val[0] = vld1q_u8(p + 0);
374*35ffd701SAndroid Build Coastguard Worker ret.val[1] = vld1q_u8(p + 16);
375*35ffd701SAndroid Build Coastguard Worker ret.val[2] = vld1q_u8(p + 32);
376*35ffd701SAndroid Build Coastguard Worker ret.val[3] = vld1q_u8(p + 48);
377*35ffd701SAndroid Build Coastguard Worker return ret;
378*35ffd701SAndroid Build Coastguard Worker }
379*35ffd701SAndroid Build Coastguard Worker #else
380*35ffd701SAndroid Build Coastguard Worker // Wraps vld1q_u8_x4
_sse2neon_vld1q_u8_x4(const uint8_t * p)381*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p)
382*35ffd701SAndroid Build Coastguard Worker {
383*35ffd701SAndroid Build Coastguard Worker return vld1q_u8_x4(p);
384*35ffd701SAndroid Build Coastguard Worker }
385*35ffd701SAndroid Build Coastguard Worker #endif
386*35ffd701SAndroid Build Coastguard Worker
387*35ffd701SAndroid Build Coastguard Worker /* Function Naming Conventions
388*35ffd701SAndroid Build Coastguard Worker * The naming convention of SSE intrinsics is straightforward. A generic SSE
389*35ffd701SAndroid Build Coastguard Worker * intrinsic function is given as follows:
390*35ffd701SAndroid Build Coastguard Worker * _mm_<name>_<data_type>
391*35ffd701SAndroid Build Coastguard Worker *
392*35ffd701SAndroid Build Coastguard Worker * The parts of this format are given as follows:
393*35ffd701SAndroid Build Coastguard Worker * 1. <name> describes the operation performed by the intrinsic
394*35ffd701SAndroid Build Coastguard Worker * 2. <data_type> identifies the data type of the function's primary arguments
395*35ffd701SAndroid Build Coastguard Worker *
396*35ffd701SAndroid Build Coastguard Worker * This last part, <data_type>, is a little complicated. It identifies the
397*35ffd701SAndroid Build Coastguard Worker * content of the input values, and can be set to any of the following values:
398*35ffd701SAndroid Build Coastguard Worker * + ps - vectors contain floats (ps stands for packed single-precision)
399*35ffd701SAndroid Build Coastguard Worker * + pd - vectors cantain doubles (pd stands for packed double-precision)
400*35ffd701SAndroid Build Coastguard Worker * + epi8/epi16/epi32/epi64 - vectors contain 8-bit/16-bit/32-bit/64-bit
401*35ffd701SAndroid Build Coastguard Worker * signed integers
402*35ffd701SAndroid Build Coastguard Worker * + epu8/epu16/epu32/epu64 - vectors contain 8-bit/16-bit/32-bit/64-bit
403*35ffd701SAndroid Build Coastguard Worker * unsigned integers
404*35ffd701SAndroid Build Coastguard Worker * + si128 - unspecified 128-bit vector or 256-bit vector
405*35ffd701SAndroid Build Coastguard Worker * + m128/m128i/m128d - identifies input vector types when they are different
406*35ffd701SAndroid Build Coastguard Worker * than the type of the returned vector
407*35ffd701SAndroid Build Coastguard Worker *
408*35ffd701SAndroid Build Coastguard Worker * For example, _mm_setzero_ps. The _mm implies that the function returns
409*35ffd701SAndroid Build Coastguard Worker * a 128-bit vector. The _ps at the end implies that the argument vectors
410*35ffd701SAndroid Build Coastguard Worker * contain floats.
411*35ffd701SAndroid Build Coastguard Worker *
412*35ffd701SAndroid Build Coastguard Worker * A complete example: Byte Shuffle - pshufb (_mm_shuffle_epi8)
413*35ffd701SAndroid Build Coastguard Worker * // Set packed 16-bit integers. 128 bits, 8 short, per 16 bits
414*35ffd701SAndroid Build Coastguard Worker * __m128i v_in = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);
415*35ffd701SAndroid Build Coastguard Worker * // Set packed 8-bit integers
416*35ffd701SAndroid Build Coastguard Worker * // 128 bits, 16 chars, per 8 bits
417*35ffd701SAndroid Build Coastguard Worker * __m128i v_perm = _mm_setr_epi8(1, 0, 2, 3, 8, 9, 10, 11,
418*35ffd701SAndroid Build Coastguard Worker * 4, 5, 12, 13, 6, 7, 14, 15);
419*35ffd701SAndroid Build Coastguard Worker * // Shuffle packed 8-bit integers
420*35ffd701SAndroid Build Coastguard Worker * __m128i v_out = _mm_shuffle_epi8(v_in, v_perm); // pshufb
421*35ffd701SAndroid Build Coastguard Worker *
422*35ffd701SAndroid Build Coastguard Worker * Data (Number, Binary, Byte Index):
423*35ffd701SAndroid Build Coastguard Worker +------+------+-------------+------+------+-------------+
424*35ffd701SAndroid Build Coastguard Worker | 1 | 2 | 3 | 4 | Number
425*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
426*35ffd701SAndroid Build Coastguard Worker | 0000 | 0001 | 0000 | 0010 | 0000 | 0011 | 0000 | 0100 | Binary
427*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
428*35ffd701SAndroid Build Coastguard Worker | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | Index
429*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
430*35ffd701SAndroid Build Coastguard Worker
431*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
432*35ffd701SAndroid Build Coastguard Worker | 5 | 6 | 7 | 8 | Number
433*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
434*35ffd701SAndroid Build Coastguard Worker | 0000 | 0101 | 0000 | 0110 | 0000 | 0111 | 0000 | 1000 | Binary
435*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
436*35ffd701SAndroid Build Coastguard Worker | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Index
437*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
438*35ffd701SAndroid Build Coastguard Worker * Index (Byte Index):
439*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
440*35ffd701SAndroid Build Coastguard Worker | 1 | 0 | 2 | 3 | 8 | 9 | 10 | 11 |
441*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
442*35ffd701SAndroid Build Coastguard Worker
443*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
444*35ffd701SAndroid Build Coastguard Worker | 4 | 5 | 12 | 13 | 6 | 7 | 14 | 15 |
445*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
446*35ffd701SAndroid Build Coastguard Worker * Result:
447*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
448*35ffd701SAndroid Build Coastguard Worker | 1 | 0 | 2 | 3 | 8 | 9 | 10 | 11 | Index
449*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
450*35ffd701SAndroid Build Coastguard Worker | 0001 | 0000 | 0000 | 0010 | 0000 | 0101 | 0000 | 0110 | Binary
451*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
452*35ffd701SAndroid Build Coastguard Worker | 256 | 2 | 5 | 6 | Number
453*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
454*35ffd701SAndroid Build Coastguard Worker
455*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
456*35ffd701SAndroid Build Coastguard Worker | 4 | 5 | 12 | 13 | 6 | 7 | 14 | 15 | Index
457*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
458*35ffd701SAndroid Build Coastguard Worker | 0000 | 0011 | 0000 | 0111 | 0000 | 0100 | 0000 | 1000 | Binary
459*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+------+------+
460*35ffd701SAndroid Build Coastguard Worker | 3 | 7 | 4 | 8 | Number
461*35ffd701SAndroid Build Coastguard Worker +------+------+------+------+------+------+-------------+
462*35ffd701SAndroid Build Coastguard Worker */
463*35ffd701SAndroid Build Coastguard Worker
464*35ffd701SAndroid Build Coastguard Worker /* Constants for use with _mm_prefetch. */
465*35ffd701SAndroid Build Coastguard Worker enum _mm_hint {
466*35ffd701SAndroid Build Coastguard Worker _MM_HINT_NTA = 0, /* load data to L1 and L2 cache, mark it as NTA */
467*35ffd701SAndroid Build Coastguard Worker _MM_HINT_T0 = 1, /* load data to L1 and L2 cache */
468*35ffd701SAndroid Build Coastguard Worker _MM_HINT_T1 = 2, /* load data to L2 cache only */
469*35ffd701SAndroid Build Coastguard Worker _MM_HINT_T2 = 3, /* load data to L2 cache only, mark it as NTA */
470*35ffd701SAndroid Build Coastguard Worker _MM_HINT_ENTA = 4, /* exclusive version of _MM_HINT_NTA */
471*35ffd701SAndroid Build Coastguard Worker _MM_HINT_ET0 = 5, /* exclusive version of _MM_HINT_T0 */
472*35ffd701SAndroid Build Coastguard Worker _MM_HINT_ET1 = 6, /* exclusive version of _MM_HINT_T1 */
473*35ffd701SAndroid Build Coastguard Worker _MM_HINT_ET2 = 7 /* exclusive version of _MM_HINT_T2 */
474*35ffd701SAndroid Build Coastguard Worker };
475*35ffd701SAndroid Build Coastguard Worker
476*35ffd701SAndroid Build Coastguard Worker // The bit field mapping to the FPCR(floating-point control register)
477*35ffd701SAndroid Build Coastguard Worker typedef struct {
478*35ffd701SAndroid Build Coastguard Worker uint16_t res0;
479*35ffd701SAndroid Build Coastguard Worker uint8_t res1 : 6;
480*35ffd701SAndroid Build Coastguard Worker uint8_t bit22 : 1;
481*35ffd701SAndroid Build Coastguard Worker uint8_t bit23 : 1;
482*35ffd701SAndroid Build Coastguard Worker uint8_t res2;
483*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
484*35ffd701SAndroid Build Coastguard Worker uint32_t res3;
485*35ffd701SAndroid Build Coastguard Worker #endif
486*35ffd701SAndroid Build Coastguard Worker } fpcr_bitfield;
487*35ffd701SAndroid Build Coastguard Worker
488*35ffd701SAndroid Build Coastguard Worker // Takes the upper 64 bits of a and places it in the low end of the result
489*35ffd701SAndroid Build Coastguard Worker // Takes the lower 64 bits of b and places it into the high end of the result.
_mm_shuffle_ps_1032(__m128 a,__m128 b)490*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_1032(__m128 a, __m128 b)
491*35ffd701SAndroid Build Coastguard Worker {
492*35ffd701SAndroid Build Coastguard Worker float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a));
493*35ffd701SAndroid Build Coastguard Worker float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b));
494*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a32, b10));
495*35ffd701SAndroid Build Coastguard Worker }
496*35ffd701SAndroid Build Coastguard Worker
497*35ffd701SAndroid Build Coastguard Worker // takes the lower two 32-bit values from a and swaps them and places in high
498*35ffd701SAndroid Build Coastguard Worker // end of result takes the higher two 32 bit values from b and swaps them and
499*35ffd701SAndroid Build Coastguard Worker // places in low end of result.
_mm_shuffle_ps_2301(__m128 a,__m128 b)500*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_2301(__m128 a, __m128 b)
501*35ffd701SAndroid Build Coastguard Worker {
502*35ffd701SAndroid Build Coastguard Worker float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a)));
503*35ffd701SAndroid Build Coastguard Worker float32x2_t b23 = vrev64_f32(vget_high_f32(vreinterpretq_f32_m128(b)));
504*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a01, b23));
505*35ffd701SAndroid Build Coastguard Worker }
506*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_0321(__m128 a,__m128 b)507*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_0321(__m128 a, __m128 b)
508*35ffd701SAndroid Build Coastguard Worker {
509*35ffd701SAndroid Build Coastguard Worker float32x2_t a21 = vget_high_f32(
510*35ffd701SAndroid Build Coastguard Worker vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3));
511*35ffd701SAndroid Build Coastguard Worker float32x2_t b03 = vget_low_f32(
512*35ffd701SAndroid Build Coastguard Worker vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3));
513*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a21, b03));
514*35ffd701SAndroid Build Coastguard Worker }
515*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_2103(__m128 a,__m128 b)516*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_2103(__m128 a, __m128 b)
517*35ffd701SAndroid Build Coastguard Worker {
518*35ffd701SAndroid Build Coastguard Worker float32x2_t a03 = vget_low_f32(
519*35ffd701SAndroid Build Coastguard Worker vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3));
520*35ffd701SAndroid Build Coastguard Worker float32x2_t b21 = vget_high_f32(
521*35ffd701SAndroid Build Coastguard Worker vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3));
522*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a03, b21));
523*35ffd701SAndroid Build Coastguard Worker }
524*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_1010(__m128 a,__m128 b)525*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_1010(__m128 a, __m128 b)
526*35ffd701SAndroid Build Coastguard Worker {
527*35ffd701SAndroid Build Coastguard Worker float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a));
528*35ffd701SAndroid Build Coastguard Worker float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b));
529*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a10, b10));
530*35ffd701SAndroid Build Coastguard Worker }
531*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_1001(__m128 a,__m128 b)532*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_1001(__m128 a, __m128 b)
533*35ffd701SAndroid Build Coastguard Worker {
534*35ffd701SAndroid Build Coastguard Worker float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a)));
535*35ffd701SAndroid Build Coastguard Worker float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b));
536*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a01, b10));
537*35ffd701SAndroid Build Coastguard Worker }
538*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_0101(__m128 a,__m128 b)539*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_0101(__m128 a, __m128 b)
540*35ffd701SAndroid Build Coastguard Worker {
541*35ffd701SAndroid Build Coastguard Worker float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a)));
542*35ffd701SAndroid Build Coastguard Worker float32x2_t b01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(b)));
543*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a01, b01));
544*35ffd701SAndroid Build Coastguard Worker }
545*35ffd701SAndroid Build Coastguard Worker
546*35ffd701SAndroid Build Coastguard Worker // keeps the low 64 bits of b in the low and puts the high 64 bits of a in the
547*35ffd701SAndroid Build Coastguard Worker // high
_mm_shuffle_ps_3210(__m128 a,__m128 b)548*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_3210(__m128 a, __m128 b)
549*35ffd701SAndroid Build Coastguard Worker {
550*35ffd701SAndroid Build Coastguard Worker float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a));
551*35ffd701SAndroid Build Coastguard Worker float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b));
552*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a10, b32));
553*35ffd701SAndroid Build Coastguard Worker }
554*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_0011(__m128 a,__m128 b)555*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_0011(__m128 a, __m128 b)
556*35ffd701SAndroid Build Coastguard Worker {
557*35ffd701SAndroid Build Coastguard Worker float32x2_t a11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 1);
558*35ffd701SAndroid Build Coastguard Worker float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0);
559*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a11, b00));
560*35ffd701SAndroid Build Coastguard Worker }
561*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_0022(__m128 a,__m128 b)562*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_0022(__m128 a, __m128 b)
563*35ffd701SAndroid Build Coastguard Worker {
564*35ffd701SAndroid Build Coastguard Worker float32x2_t a22 =
565*35ffd701SAndroid Build Coastguard Worker vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0);
566*35ffd701SAndroid Build Coastguard Worker float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0);
567*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a22, b00));
568*35ffd701SAndroid Build Coastguard Worker }
569*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_2200(__m128 a,__m128 b)570*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_2200(__m128 a, __m128 b)
571*35ffd701SAndroid Build Coastguard Worker {
572*35ffd701SAndroid Build Coastguard Worker float32x2_t a00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 0);
573*35ffd701SAndroid Build Coastguard Worker float32x2_t b22 =
574*35ffd701SAndroid Build Coastguard Worker vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(b)), 0);
575*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a00, b22));
576*35ffd701SAndroid Build Coastguard Worker }
577*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_3202(__m128 a,__m128 b)578*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_3202(__m128 a, __m128 b)
579*35ffd701SAndroid Build Coastguard Worker {
580*35ffd701SAndroid Build Coastguard Worker float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0);
581*35ffd701SAndroid Build Coastguard Worker float32x2_t a22 =
582*35ffd701SAndroid Build Coastguard Worker vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0);
583*35ffd701SAndroid Build Coastguard Worker float32x2_t a02 = vset_lane_f32(a0, a22, 1); /* TODO: use vzip ?*/
584*35ffd701SAndroid Build Coastguard Worker float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b));
585*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a02, b32));
586*35ffd701SAndroid Build Coastguard Worker }
587*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_1133(__m128 a,__m128 b)588*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_1133(__m128 a, __m128 b)
589*35ffd701SAndroid Build Coastguard Worker {
590*35ffd701SAndroid Build Coastguard Worker float32x2_t a33 =
591*35ffd701SAndroid Build Coastguard Worker vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 1);
592*35ffd701SAndroid Build Coastguard Worker float32x2_t b11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 1);
593*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a33, b11));
594*35ffd701SAndroid Build Coastguard Worker }
595*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_2010(__m128 a,__m128 b)596*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_2010(__m128 a, __m128 b)
597*35ffd701SAndroid Build Coastguard Worker {
598*35ffd701SAndroid Build Coastguard Worker float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a));
599*35ffd701SAndroid Build Coastguard Worker float32_t b2 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 2);
600*35ffd701SAndroid Build Coastguard Worker float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0);
601*35ffd701SAndroid Build Coastguard Worker float32x2_t b20 = vset_lane_f32(b2, b00, 1);
602*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a10, b20));
603*35ffd701SAndroid Build Coastguard Worker }
604*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_2001(__m128 a,__m128 b)605*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_2001(__m128 a, __m128 b)
606*35ffd701SAndroid Build Coastguard Worker {
607*35ffd701SAndroid Build Coastguard Worker float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a)));
608*35ffd701SAndroid Build Coastguard Worker float32_t b2 = vgetq_lane_f32(b, 2);
609*35ffd701SAndroid Build Coastguard Worker float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0);
610*35ffd701SAndroid Build Coastguard Worker float32x2_t b20 = vset_lane_f32(b2, b00, 1);
611*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a01, b20));
612*35ffd701SAndroid Build Coastguard Worker }
613*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_ps_2032(__m128 a,__m128 b)614*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b)
615*35ffd701SAndroid Build Coastguard Worker {
616*35ffd701SAndroid Build Coastguard Worker float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a));
617*35ffd701SAndroid Build Coastguard Worker float32_t b2 = vgetq_lane_f32(b, 2);
618*35ffd701SAndroid Build Coastguard Worker float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0);
619*35ffd701SAndroid Build Coastguard Worker float32x2_t b20 = vset_lane_f32(b2, b00, 1);
620*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a32, b20));
621*35ffd701SAndroid Build Coastguard Worker }
622*35ffd701SAndroid Build Coastguard Worker
623*35ffd701SAndroid Build Coastguard Worker // Kahan summation for accurate summation of floating-point numbers.
624*35ffd701SAndroid Build Coastguard Worker // http://blog.zachbjornson.com/2019/08/11/fast-float-summation.html
_sse2neon_kadd_f32(float * sum,float * c,float y)625*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _sse2neon_kadd_f32(float *sum, float *c, float y)
626*35ffd701SAndroid Build Coastguard Worker {
627*35ffd701SAndroid Build Coastguard Worker y -= *c;
628*35ffd701SAndroid Build Coastguard Worker float t = *sum + y;
629*35ffd701SAndroid Build Coastguard Worker *c = (t - *sum) - y;
630*35ffd701SAndroid Build Coastguard Worker *sum = t;
631*35ffd701SAndroid Build Coastguard Worker }
632*35ffd701SAndroid Build Coastguard Worker
633*35ffd701SAndroid Build Coastguard Worker #if defined(__ARM_FEATURE_CRYPTO)
634*35ffd701SAndroid Build Coastguard Worker // Wraps vmull_p64
_sse2neon_vmull_p64(uint64x1_t _a,uint64x1_t _b)635*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b)
636*35ffd701SAndroid Build Coastguard Worker {
637*35ffd701SAndroid Build Coastguard Worker poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0);
638*35ffd701SAndroid Build Coastguard Worker poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0);
639*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_u64_p128(vmull_p64(a, b));
640*35ffd701SAndroid Build Coastguard Worker }
641*35ffd701SAndroid Build Coastguard Worker #else // ARMv7 polyfill
642*35ffd701SAndroid Build Coastguard Worker // ARMv7/some A64 lacks vmull_p64, but it has vmull_p8.
643*35ffd701SAndroid Build Coastguard Worker //
644*35ffd701SAndroid Build Coastguard Worker // vmull_p8 calculates 8 8-bit->16-bit polynomial multiplies, but we need a
645*35ffd701SAndroid Build Coastguard Worker // 64-bit->128-bit polynomial multiply.
646*35ffd701SAndroid Build Coastguard Worker //
647*35ffd701SAndroid Build Coastguard Worker // It needs some work and is somewhat slow, but it is still faster than all
648*35ffd701SAndroid Build Coastguard Worker // known scalar methods.
649*35ffd701SAndroid Build Coastguard Worker //
650*35ffd701SAndroid Build Coastguard Worker // Algorithm adapted to C from
651*35ffd701SAndroid Build Coastguard Worker // https://www.workofard.com/2017/07/ghash-for-low-end-cores/, which is adapted
652*35ffd701SAndroid Build Coastguard Worker // from "Fast Software Polynomial Multiplication on ARM Processors Using the
653*35ffd701SAndroid Build Coastguard Worker // NEON Engine" by Danilo Camara, Conrado Gouvea, Julio Lopez and Ricardo Dahab
654*35ffd701SAndroid Build Coastguard Worker // (https://hal.inria.fr/hal-01506572)
_sse2neon_vmull_p64(uint64x1_t _a,uint64x1_t _b)655*35ffd701SAndroid Build Coastguard Worker static uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b)
656*35ffd701SAndroid Build Coastguard Worker {
657*35ffd701SAndroid Build Coastguard Worker poly8x8_t a = vreinterpret_p8_u64(_a);
658*35ffd701SAndroid Build Coastguard Worker poly8x8_t b = vreinterpret_p8_u64(_b);
659*35ffd701SAndroid Build Coastguard Worker
660*35ffd701SAndroid Build Coastguard Worker // Masks
661*35ffd701SAndroid Build Coastguard Worker uint8x16_t k48_32 = vcombine_u8(vcreate_u8(0x0000ffffffffffff),
662*35ffd701SAndroid Build Coastguard Worker vcreate_u8(0x00000000ffffffff));
663*35ffd701SAndroid Build Coastguard Worker uint8x16_t k16_00 = vcombine_u8(vcreate_u8(0x000000000000ffff),
664*35ffd701SAndroid Build Coastguard Worker vcreate_u8(0x0000000000000000));
665*35ffd701SAndroid Build Coastguard Worker
666*35ffd701SAndroid Build Coastguard Worker // Do the multiplies, rotating with vext to get all combinations
667*35ffd701SAndroid Build Coastguard Worker uint8x16_t d = vreinterpretq_u8_p16(vmull_p8(a, b)); // D = A0 * B0
668*35ffd701SAndroid Build Coastguard Worker uint8x16_t e =
669*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 1))); // E = A0 * B1
670*35ffd701SAndroid Build Coastguard Worker uint8x16_t f =
671*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 1), b)); // F = A1 * B0
672*35ffd701SAndroid Build Coastguard Worker uint8x16_t g =
673*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 2))); // G = A0 * B2
674*35ffd701SAndroid Build Coastguard Worker uint8x16_t h =
675*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 2), b)); // H = A2 * B0
676*35ffd701SAndroid Build Coastguard Worker uint8x16_t i =
677*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 3))); // I = A0 * B3
678*35ffd701SAndroid Build Coastguard Worker uint8x16_t j =
679*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 3), b)); // J = A3 * B0
680*35ffd701SAndroid Build Coastguard Worker uint8x16_t k =
681*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 4))); // L = A0 * B4
682*35ffd701SAndroid Build Coastguard Worker
683*35ffd701SAndroid Build Coastguard Worker // Add cross products
684*35ffd701SAndroid Build Coastguard Worker uint8x16_t l = veorq_u8(e, f); // L = E + F
685*35ffd701SAndroid Build Coastguard Worker uint8x16_t m = veorq_u8(g, h); // M = G + H
686*35ffd701SAndroid Build Coastguard Worker uint8x16_t n = veorq_u8(i, j); // N = I + J
687*35ffd701SAndroid Build Coastguard Worker
688*35ffd701SAndroid Build Coastguard Worker // Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL
689*35ffd701SAndroid Build Coastguard Worker // instructions.
690*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
691*35ffd701SAndroid Build Coastguard Worker uint8x16_t lm_p0 = vreinterpretq_u8_u64(
692*35ffd701SAndroid Build Coastguard Worker vzip1q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m)));
693*35ffd701SAndroid Build Coastguard Worker uint8x16_t lm_p1 = vreinterpretq_u8_u64(
694*35ffd701SAndroid Build Coastguard Worker vzip2q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m)));
695*35ffd701SAndroid Build Coastguard Worker uint8x16_t nk_p0 = vreinterpretq_u8_u64(
696*35ffd701SAndroid Build Coastguard Worker vzip1q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k)));
697*35ffd701SAndroid Build Coastguard Worker uint8x16_t nk_p1 = vreinterpretq_u8_u64(
698*35ffd701SAndroid Build Coastguard Worker vzip2q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k)));
699*35ffd701SAndroid Build Coastguard Worker #else
700*35ffd701SAndroid Build Coastguard Worker uint8x16_t lm_p0 = vcombine_u8(vget_low_u8(l), vget_low_u8(m));
701*35ffd701SAndroid Build Coastguard Worker uint8x16_t lm_p1 = vcombine_u8(vget_high_u8(l), vget_high_u8(m));
702*35ffd701SAndroid Build Coastguard Worker uint8x16_t nk_p0 = vcombine_u8(vget_low_u8(n), vget_low_u8(k));
703*35ffd701SAndroid Build Coastguard Worker uint8x16_t nk_p1 = vcombine_u8(vget_high_u8(n), vget_high_u8(k));
704*35ffd701SAndroid Build Coastguard Worker #endif
705*35ffd701SAndroid Build Coastguard Worker // t0 = (L) (P0 + P1) << 8
706*35ffd701SAndroid Build Coastguard Worker // t1 = (M) (P2 + P3) << 16
707*35ffd701SAndroid Build Coastguard Worker uint8x16_t t0t1_tmp = veorq_u8(lm_p0, lm_p1);
708*35ffd701SAndroid Build Coastguard Worker uint8x16_t t0t1_h = vandq_u8(lm_p1, k48_32);
709*35ffd701SAndroid Build Coastguard Worker uint8x16_t t0t1_l = veorq_u8(t0t1_tmp, t0t1_h);
710*35ffd701SAndroid Build Coastguard Worker
711*35ffd701SAndroid Build Coastguard Worker // t2 = (N) (P4 + P5) << 24
712*35ffd701SAndroid Build Coastguard Worker // t3 = (K) (P6 + P7) << 32
713*35ffd701SAndroid Build Coastguard Worker uint8x16_t t2t3_tmp = veorq_u8(nk_p0, nk_p1);
714*35ffd701SAndroid Build Coastguard Worker uint8x16_t t2t3_h = vandq_u8(nk_p1, k16_00);
715*35ffd701SAndroid Build Coastguard Worker uint8x16_t t2t3_l = veorq_u8(t2t3_tmp, t2t3_h);
716*35ffd701SAndroid Build Coastguard Worker
717*35ffd701SAndroid Build Coastguard Worker // De-interleave
718*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
719*35ffd701SAndroid Build Coastguard Worker uint8x16_t t0 = vreinterpretq_u8_u64(
720*35ffd701SAndroid Build Coastguard Worker vuzp1q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h)));
721*35ffd701SAndroid Build Coastguard Worker uint8x16_t t1 = vreinterpretq_u8_u64(
722*35ffd701SAndroid Build Coastguard Worker vuzp2q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h)));
723*35ffd701SAndroid Build Coastguard Worker uint8x16_t t2 = vreinterpretq_u8_u64(
724*35ffd701SAndroid Build Coastguard Worker vuzp1q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h)));
725*35ffd701SAndroid Build Coastguard Worker uint8x16_t t3 = vreinterpretq_u8_u64(
726*35ffd701SAndroid Build Coastguard Worker vuzp2q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h)));
727*35ffd701SAndroid Build Coastguard Worker #else
728*35ffd701SAndroid Build Coastguard Worker uint8x16_t t1 = vcombine_u8(vget_high_u8(t0t1_l), vget_high_u8(t0t1_h));
729*35ffd701SAndroid Build Coastguard Worker uint8x16_t t0 = vcombine_u8(vget_low_u8(t0t1_l), vget_low_u8(t0t1_h));
730*35ffd701SAndroid Build Coastguard Worker uint8x16_t t3 = vcombine_u8(vget_high_u8(t2t3_l), vget_high_u8(t2t3_h));
731*35ffd701SAndroid Build Coastguard Worker uint8x16_t t2 = vcombine_u8(vget_low_u8(t2t3_l), vget_low_u8(t2t3_h));
732*35ffd701SAndroid Build Coastguard Worker #endif
733*35ffd701SAndroid Build Coastguard Worker // Shift the cross products
734*35ffd701SAndroid Build Coastguard Worker uint8x16_t t0_shift = vextq_u8(t0, t0, 15); // t0 << 8
735*35ffd701SAndroid Build Coastguard Worker uint8x16_t t1_shift = vextq_u8(t1, t1, 14); // t1 << 16
736*35ffd701SAndroid Build Coastguard Worker uint8x16_t t2_shift = vextq_u8(t2, t2, 13); // t2 << 24
737*35ffd701SAndroid Build Coastguard Worker uint8x16_t t3_shift = vextq_u8(t3, t3, 12); // t3 << 32
738*35ffd701SAndroid Build Coastguard Worker
739*35ffd701SAndroid Build Coastguard Worker // Accumulate the products
740*35ffd701SAndroid Build Coastguard Worker uint8x16_t cross1 = veorq_u8(t0_shift, t1_shift);
741*35ffd701SAndroid Build Coastguard Worker uint8x16_t cross2 = veorq_u8(t2_shift, t3_shift);
742*35ffd701SAndroid Build Coastguard Worker uint8x16_t mix = veorq_u8(d, cross1);
743*35ffd701SAndroid Build Coastguard Worker uint8x16_t r = veorq_u8(mix, cross2);
744*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_u64_u8(r);
745*35ffd701SAndroid Build Coastguard Worker }
746*35ffd701SAndroid Build Coastguard Worker #endif // ARMv7 polyfill
747*35ffd701SAndroid Build Coastguard Worker
748*35ffd701SAndroid Build Coastguard Worker // C equivalent:
749*35ffd701SAndroid Build Coastguard Worker // __m128i _mm_shuffle_epi32_default(__m128i a,
750*35ffd701SAndroid Build Coastguard Worker // __constrange(0, 255) int imm) {
751*35ffd701SAndroid Build Coastguard Worker // __m128i ret;
752*35ffd701SAndroid Build Coastguard Worker // ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3];
753*35ffd701SAndroid Build Coastguard Worker // ret[2] = a[(imm >> 4) & 0x03]; ret[3] = a[(imm >> 6) & 0x03];
754*35ffd701SAndroid Build Coastguard Worker // return ret;
755*35ffd701SAndroid Build Coastguard Worker // }
756*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_epi32_default(a, imm) \
757*35ffd701SAndroid Build Coastguard Worker __extension__({ \
758*35ffd701SAndroid Build Coastguard Worker int32x4_t ret; \
759*35ffd701SAndroid Build Coastguard Worker ret = vmovq_n_s32( \
760*35ffd701SAndroid Build Coastguard Worker vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm) & (0x3))); \
761*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s32( \
762*35ffd701SAndroid Build Coastguard Worker vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 2) & 0x3), \
763*35ffd701SAndroid Build Coastguard Worker ret, 1); \
764*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s32( \
765*35ffd701SAndroid Build Coastguard Worker vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 4) & 0x3), \
766*35ffd701SAndroid Build Coastguard Worker ret, 2); \
767*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s32( \
768*35ffd701SAndroid Build Coastguard Worker vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \
769*35ffd701SAndroid Build Coastguard Worker ret, 3); \
770*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s32(ret); \
771*35ffd701SAndroid Build Coastguard Worker })
772*35ffd701SAndroid Build Coastguard Worker
773*35ffd701SAndroid Build Coastguard Worker // Takes the upper 64 bits of a and places it in the low end of the result
774*35ffd701SAndroid Build Coastguard Worker // Takes the lower 64 bits of a and places it into the high end of the result.
_mm_shuffle_epi_1032(__m128i a)775*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_1032(__m128i a)
776*35ffd701SAndroid Build Coastguard Worker {
777*35ffd701SAndroid Build Coastguard Worker int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a));
778*35ffd701SAndroid Build Coastguard Worker int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a));
779*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(a32, a10));
780*35ffd701SAndroid Build Coastguard Worker }
781*35ffd701SAndroid Build Coastguard Worker
782*35ffd701SAndroid Build Coastguard Worker // takes the lower two 32-bit values from a and swaps them and places in low end
783*35ffd701SAndroid Build Coastguard Worker // of result takes the higher two 32 bit values from a and swaps them and places
784*35ffd701SAndroid Build Coastguard Worker // in high end of result.
_mm_shuffle_epi_2301(__m128i a)785*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_2301(__m128i a)
786*35ffd701SAndroid Build Coastguard Worker {
787*35ffd701SAndroid Build Coastguard Worker int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a)));
788*35ffd701SAndroid Build Coastguard Worker int32x2_t a23 = vrev64_s32(vget_high_s32(vreinterpretq_s32_m128i(a)));
789*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(a01, a23));
790*35ffd701SAndroid Build Coastguard Worker }
791*35ffd701SAndroid Build Coastguard Worker
792*35ffd701SAndroid Build Coastguard Worker // rotates the least significant 32 bits into the most significant 32 bits, and
793*35ffd701SAndroid Build Coastguard Worker // shifts the rest down
_mm_shuffle_epi_0321(__m128i a)794*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_0321(__m128i a)
795*35ffd701SAndroid Build Coastguard Worker {
796*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
797*35ffd701SAndroid Build Coastguard Worker vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 1));
798*35ffd701SAndroid Build Coastguard Worker }
799*35ffd701SAndroid Build Coastguard Worker
800*35ffd701SAndroid Build Coastguard Worker // rotates the most significant 32 bits into the least significant 32 bits, and
801*35ffd701SAndroid Build Coastguard Worker // shifts the rest up
_mm_shuffle_epi_2103(__m128i a)802*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_2103(__m128i a)
803*35ffd701SAndroid Build Coastguard Worker {
804*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
805*35ffd701SAndroid Build Coastguard Worker vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 3));
806*35ffd701SAndroid Build Coastguard Worker }
807*35ffd701SAndroid Build Coastguard Worker
808*35ffd701SAndroid Build Coastguard Worker // gets the lower 64 bits of a, and places it in the upper 64 bits
809*35ffd701SAndroid Build Coastguard Worker // gets the lower 64 bits of a and places it in the lower 64 bits
_mm_shuffle_epi_1010(__m128i a)810*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_1010(__m128i a)
811*35ffd701SAndroid Build Coastguard Worker {
812*35ffd701SAndroid Build Coastguard Worker int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a));
813*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(a10, a10));
814*35ffd701SAndroid Build Coastguard Worker }
815*35ffd701SAndroid Build Coastguard Worker
816*35ffd701SAndroid Build Coastguard Worker // gets the lower 64 bits of a, swaps the 0 and 1 elements, and places it in the
817*35ffd701SAndroid Build Coastguard Worker // lower 64 bits gets the lower 64 bits of a, and places it in the upper 64 bits
_mm_shuffle_epi_1001(__m128i a)818*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_1001(__m128i a)
819*35ffd701SAndroid Build Coastguard Worker {
820*35ffd701SAndroid Build Coastguard Worker int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a)));
821*35ffd701SAndroid Build Coastguard Worker int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a));
822*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(a01, a10));
823*35ffd701SAndroid Build Coastguard Worker }
824*35ffd701SAndroid Build Coastguard Worker
825*35ffd701SAndroid Build Coastguard Worker // gets the lower 64 bits of a, swaps the 0 and 1 elements and places it in the
826*35ffd701SAndroid Build Coastguard Worker // upper 64 bits gets the lower 64 bits of a, swaps the 0 and 1 elements, and
827*35ffd701SAndroid Build Coastguard Worker // places it in the lower 64 bits
_mm_shuffle_epi_0101(__m128i a)828*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_0101(__m128i a)
829*35ffd701SAndroid Build Coastguard Worker {
830*35ffd701SAndroid Build Coastguard Worker int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a)));
831*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(a01, a01));
832*35ffd701SAndroid Build Coastguard Worker }
833*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_epi_2211(__m128i a)834*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_2211(__m128i a)
835*35ffd701SAndroid Build Coastguard Worker {
836*35ffd701SAndroid Build Coastguard Worker int32x2_t a11 = vdup_lane_s32(vget_low_s32(vreinterpretq_s32_m128i(a)), 1);
837*35ffd701SAndroid Build Coastguard Worker int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0);
838*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(a11, a22));
839*35ffd701SAndroid Build Coastguard Worker }
840*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_epi_0122(__m128i a)841*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_0122(__m128i a)
842*35ffd701SAndroid Build Coastguard Worker {
843*35ffd701SAndroid Build Coastguard Worker int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0);
844*35ffd701SAndroid Build Coastguard Worker int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a)));
845*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(a22, a01));
846*35ffd701SAndroid Build Coastguard Worker }
847*35ffd701SAndroid Build Coastguard Worker
_mm_shuffle_epi_3332(__m128i a)848*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a)
849*35ffd701SAndroid Build Coastguard Worker {
850*35ffd701SAndroid Build Coastguard Worker int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a));
851*35ffd701SAndroid Build Coastguard Worker int32x2_t a33 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 1);
852*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(a32, a33));
853*35ffd701SAndroid Build Coastguard Worker }
854*35ffd701SAndroid Build Coastguard Worker
855*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a, __constrange(0,255)
856*35ffd701SAndroid Build Coastguard Worker // int imm)
857*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
858*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_epi32_splat(a, imm) \
859*35ffd701SAndroid Build Coastguard Worker __extension__({ \
860*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s32( \
861*35ffd701SAndroid Build Coastguard Worker vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))); \
862*35ffd701SAndroid Build Coastguard Worker })
863*35ffd701SAndroid Build Coastguard Worker #else
864*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_epi32_splat(a, imm) \
865*35ffd701SAndroid Build Coastguard Worker __extension__({ \
866*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s32( \
867*35ffd701SAndroid Build Coastguard Worker vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))); \
868*35ffd701SAndroid Build Coastguard Worker })
869*35ffd701SAndroid Build Coastguard Worker #endif
870*35ffd701SAndroid Build Coastguard Worker
871*35ffd701SAndroid Build Coastguard Worker // NEON does not support a general purpose permute intrinsic
872*35ffd701SAndroid Build Coastguard Worker // Selects four specific single-precision, floating-point values from a and b,
873*35ffd701SAndroid Build Coastguard Worker // based on the mask i.
874*35ffd701SAndroid Build Coastguard Worker //
875*35ffd701SAndroid Build Coastguard Worker // C equivalent:
876*35ffd701SAndroid Build Coastguard Worker // __m128 _mm_shuffle_ps_default(__m128 a, __m128 b,
877*35ffd701SAndroid Build Coastguard Worker // __constrange(0, 255) int imm) {
878*35ffd701SAndroid Build Coastguard Worker // __m128 ret;
879*35ffd701SAndroid Build Coastguard Worker // ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3];
880*35ffd701SAndroid Build Coastguard Worker // ret[2] = b[(imm >> 4) & 0x03]; ret[3] = b[(imm >> 6) & 0x03];
881*35ffd701SAndroid Build Coastguard Worker // return ret;
882*35ffd701SAndroid Build Coastguard Worker // }
883*35ffd701SAndroid Build Coastguard Worker //
884*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/5f0858x0(v=vs.100).aspx
885*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_ps_default(a, b, imm) \
886*35ffd701SAndroid Build Coastguard Worker __extension__({ \
887*35ffd701SAndroid Build Coastguard Worker float32x4_t ret; \
888*35ffd701SAndroid Build Coastguard Worker ret = vmovq_n_f32( \
889*35ffd701SAndroid Build Coastguard Worker vgetq_lane_f32(vreinterpretq_f32_m128(a), (imm) & (0x3))); \
890*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_f32( \
891*35ffd701SAndroid Build Coastguard Worker vgetq_lane_f32(vreinterpretq_f32_m128(a), ((imm) >> 2) & 0x3), \
892*35ffd701SAndroid Build Coastguard Worker ret, 1); \
893*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_f32( \
894*35ffd701SAndroid Build Coastguard Worker vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 4) & 0x3), \
895*35ffd701SAndroid Build Coastguard Worker ret, 2); \
896*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_f32( \
897*35ffd701SAndroid Build Coastguard Worker vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 6) & 0x3), \
898*35ffd701SAndroid Build Coastguard Worker ret, 3); \
899*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128_f32(ret); \
900*35ffd701SAndroid Build Coastguard Worker })
901*35ffd701SAndroid Build Coastguard Worker
902*35ffd701SAndroid Build Coastguard Worker // Shuffles the lower 4 signed or unsigned 16-bit integers in a as specified
903*35ffd701SAndroid Build Coastguard Worker // by imm.
904*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/y41dkk37(v=vs.100)
905*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_shufflelo_epi16_function(__m128i a,
906*35ffd701SAndroid Build Coastguard Worker // __constrange(0,255) int
907*35ffd701SAndroid Build Coastguard Worker // imm)
908*35ffd701SAndroid Build Coastguard Worker #define _mm_shufflelo_epi16_function(a, imm) \
909*35ffd701SAndroid Build Coastguard Worker __extension__({ \
910*35ffd701SAndroid Build Coastguard Worker int16x8_t ret = vreinterpretq_s16_m128i(a); \
911*35ffd701SAndroid Build Coastguard Worker int16x4_t lowBits = vget_low_s16(ret); \
912*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s16(vget_lane_s16(lowBits, (imm) & (0x3)), ret, 0); \
913*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 2) & 0x3), ret, \
914*35ffd701SAndroid Build Coastguard Worker 1); \
915*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 4) & 0x3), ret, \
916*35ffd701SAndroid Build Coastguard Worker 2); \
917*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 6) & 0x3), ret, \
918*35ffd701SAndroid Build Coastguard Worker 3); \
919*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s16(ret); \
920*35ffd701SAndroid Build Coastguard Worker })
921*35ffd701SAndroid Build Coastguard Worker
922*35ffd701SAndroid Build Coastguard Worker // Shuffles the upper 4 signed or unsigned 16-bit integers in a as specified
923*35ffd701SAndroid Build Coastguard Worker // by imm.
924*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/13ywktbs(v=vs.100).aspx
925*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_shufflehi_epi16_function(__m128i a,
926*35ffd701SAndroid Build Coastguard Worker // __constrange(0,255) int
927*35ffd701SAndroid Build Coastguard Worker // imm)
928*35ffd701SAndroid Build Coastguard Worker #define _mm_shufflehi_epi16_function(a, imm) \
929*35ffd701SAndroid Build Coastguard Worker __extension__({ \
930*35ffd701SAndroid Build Coastguard Worker int16x8_t ret = vreinterpretq_s16_m128i(a); \
931*35ffd701SAndroid Build Coastguard Worker int16x4_t highBits = vget_high_s16(ret); \
932*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s16(vget_lane_s16(highBits, (imm) & (0x3)), ret, 4); \
933*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 2) & 0x3), ret, \
934*35ffd701SAndroid Build Coastguard Worker 5); \
935*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 4) & 0x3), ret, \
936*35ffd701SAndroid Build Coastguard Worker 6); \
937*35ffd701SAndroid Build Coastguard Worker ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 6) & 0x3), ret, \
938*35ffd701SAndroid Build Coastguard Worker 7); \
939*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s16(ret); \
940*35ffd701SAndroid Build Coastguard Worker })
941*35ffd701SAndroid Build Coastguard Worker
942*35ffd701SAndroid Build Coastguard Worker /* SSE */
943*35ffd701SAndroid Build Coastguard Worker
944*35ffd701SAndroid Build Coastguard Worker // Adds the four single-precision, floating-point values of a and b.
945*35ffd701SAndroid Build Coastguard Worker //
946*35ffd701SAndroid Build Coastguard Worker // r0 := a0 + b0
947*35ffd701SAndroid Build Coastguard Worker // r1 := a1 + b1
948*35ffd701SAndroid Build Coastguard Worker // r2 := a2 + b2
949*35ffd701SAndroid Build Coastguard Worker // r3 := a3 + b3
950*35ffd701SAndroid Build Coastguard Worker //
951*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/c9848chc(v=vs.100).aspx
_mm_add_ps(__m128 a,__m128 b)952*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_add_ps(__m128 a, __m128 b)
953*35ffd701SAndroid Build Coastguard Worker {
954*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
955*35ffd701SAndroid Build Coastguard Worker vaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
956*35ffd701SAndroid Build Coastguard Worker }
957*35ffd701SAndroid Build Coastguard Worker
958*35ffd701SAndroid Build Coastguard Worker // adds the scalar single-precision floating point values of a and b.
959*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/be94x2y6(v=vs.100).aspx
_mm_add_ss(__m128 a,__m128 b)960*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_add_ss(__m128 a, __m128 b)
961*35ffd701SAndroid Build Coastguard Worker {
962*35ffd701SAndroid Build Coastguard Worker float32_t b0 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 0);
963*35ffd701SAndroid Build Coastguard Worker float32x4_t value = vsetq_lane_f32(b0, vdupq_n_f32(0), 0);
964*35ffd701SAndroid Build Coastguard Worker // the upper values in the result must be the remnants of <a>.
965*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vaddq_f32(a, value));
966*35ffd701SAndroid Build Coastguard Worker }
967*35ffd701SAndroid Build Coastguard Worker
968*35ffd701SAndroid Build Coastguard Worker // Computes the bitwise AND of the four single-precision, floating-point values
969*35ffd701SAndroid Build Coastguard Worker // of a and b.
970*35ffd701SAndroid Build Coastguard Worker //
971*35ffd701SAndroid Build Coastguard Worker // r0 := a0 & b0
972*35ffd701SAndroid Build Coastguard Worker // r1 := a1 & b1
973*35ffd701SAndroid Build Coastguard Worker // r2 := a2 & b2
974*35ffd701SAndroid Build Coastguard Worker // r3 := a3 & b3
975*35ffd701SAndroid Build Coastguard Worker //
976*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/73ck1xc5(v=vs.100).aspx
_mm_and_ps(__m128 a,__m128 b)977*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b)
978*35ffd701SAndroid Build Coastguard Worker {
979*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_s32(
980*35ffd701SAndroid Build Coastguard Worker vandq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b)));
981*35ffd701SAndroid Build Coastguard Worker }
982*35ffd701SAndroid Build Coastguard Worker
983*35ffd701SAndroid Build Coastguard Worker // Computes the bitwise AND-NOT of the four single-precision, floating-point
984*35ffd701SAndroid Build Coastguard Worker // values of a and b.
985*35ffd701SAndroid Build Coastguard Worker //
986*35ffd701SAndroid Build Coastguard Worker // r0 := ~a0 & b0
987*35ffd701SAndroid Build Coastguard Worker // r1 := ~a1 & b1
988*35ffd701SAndroid Build Coastguard Worker // r2 := ~a2 & b2
989*35ffd701SAndroid Build Coastguard Worker // r3 := ~a3 & b3
990*35ffd701SAndroid Build Coastguard Worker //
991*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/68h7wd02(v=vs.100).aspx
_mm_andnot_ps(__m128 a,__m128 b)992*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_andnot_ps(__m128 a, __m128 b)
993*35ffd701SAndroid Build Coastguard Worker {
994*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_s32(
995*35ffd701SAndroid Build Coastguard Worker vbicq_s32(vreinterpretq_s32_m128(b),
996*35ffd701SAndroid Build Coastguard Worker vreinterpretq_s32_m128(a))); // *NOTE* argument swap
997*35ffd701SAndroid Build Coastguard Worker }
998*35ffd701SAndroid Build Coastguard Worker
999*35ffd701SAndroid Build Coastguard Worker // Average packed unsigned 16-bit integers in a and b, and store the results in
1000*35ffd701SAndroid Build Coastguard Worker // dst.
1001*35ffd701SAndroid Build Coastguard Worker //
1002*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
1003*35ffd701SAndroid Build Coastguard Worker // i := j*16
1004*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1
1005*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1006*35ffd701SAndroid Build Coastguard Worker //
1007*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu16
_mm_avg_pu16(__m64 a,__m64 b)1008*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_avg_pu16(__m64 a, __m64 b)
1009*35ffd701SAndroid Build Coastguard Worker {
1010*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_u16(
1011*35ffd701SAndroid Build Coastguard Worker vrhadd_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b)));
1012*35ffd701SAndroid Build Coastguard Worker }
1013*35ffd701SAndroid Build Coastguard Worker
1014*35ffd701SAndroid Build Coastguard Worker // Average packed unsigned 8-bit integers in a and b, and store the results in
1015*35ffd701SAndroid Build Coastguard Worker // dst.
1016*35ffd701SAndroid Build Coastguard Worker //
1017*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
1018*35ffd701SAndroid Build Coastguard Worker // i := j*8
1019*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1
1020*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1021*35ffd701SAndroid Build Coastguard Worker //
1022*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu8
_mm_avg_pu8(__m64 a,__m64 b)1023*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_avg_pu8(__m64 a, __m64 b)
1024*35ffd701SAndroid Build Coastguard Worker {
1025*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_u8(
1026*35ffd701SAndroid Build Coastguard Worker vrhadd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b)));
1027*35ffd701SAndroid Build Coastguard Worker }
1028*35ffd701SAndroid Build Coastguard Worker
1029*35ffd701SAndroid Build Coastguard Worker // Compares for equality.
1030*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/36aectz5(v=vs.100).aspx
_mm_cmpeq_ps(__m128 a,__m128 b)1031*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpeq_ps(__m128 a, __m128 b)
1032*35ffd701SAndroid Build Coastguard Worker {
1033*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_u32(
1034*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
1035*35ffd701SAndroid Build Coastguard Worker }
1036*35ffd701SAndroid Build Coastguard Worker
1037*35ffd701SAndroid Build Coastguard Worker // Compares for equality.
1038*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/k423z28e(v=vs.100)
_mm_cmpeq_ss(__m128 a,__m128 b)1039*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpeq_ss(__m128 a, __m128 b)
1040*35ffd701SAndroid Build Coastguard Worker {
1041*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_cmpeq_ps(a, b));
1042*35ffd701SAndroid Build Coastguard Worker }
1043*35ffd701SAndroid Build Coastguard Worker
1044*35ffd701SAndroid Build Coastguard Worker // Compares for greater than or equal.
1045*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/fs813y2t(v=vs.100).aspx
_mm_cmpge_ps(__m128 a,__m128 b)1046*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b)
1047*35ffd701SAndroid Build Coastguard Worker {
1048*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_u32(
1049*35ffd701SAndroid Build Coastguard Worker vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
1050*35ffd701SAndroid Build Coastguard Worker }
1051*35ffd701SAndroid Build Coastguard Worker
1052*35ffd701SAndroid Build Coastguard Worker // Compares for greater than or equal.
1053*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/kesh3ddc(v=vs.100)
_mm_cmpge_ss(__m128 a,__m128 b)1054*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpge_ss(__m128 a, __m128 b)
1055*35ffd701SAndroid Build Coastguard Worker {
1056*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_cmpge_ps(a, b));
1057*35ffd701SAndroid Build Coastguard Worker }
1058*35ffd701SAndroid Build Coastguard Worker
1059*35ffd701SAndroid Build Coastguard Worker // Compares for greater than.
1060*35ffd701SAndroid Build Coastguard Worker //
1061*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 > b0) ? 0xffffffff : 0x0
1062*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 > b1) ? 0xffffffff : 0x0
1063*35ffd701SAndroid Build Coastguard Worker // r2 := (a2 > b2) ? 0xffffffff : 0x0
1064*35ffd701SAndroid Build Coastguard Worker // r3 := (a3 > b3) ? 0xffffffff : 0x0
1065*35ffd701SAndroid Build Coastguard Worker //
1066*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/11dy102s(v=vs.100).aspx
_mm_cmpgt_ps(__m128 a,__m128 b)1067*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpgt_ps(__m128 a, __m128 b)
1068*35ffd701SAndroid Build Coastguard Worker {
1069*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_u32(
1070*35ffd701SAndroid Build Coastguard Worker vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
1071*35ffd701SAndroid Build Coastguard Worker }
1072*35ffd701SAndroid Build Coastguard Worker
1073*35ffd701SAndroid Build Coastguard Worker // Compares for greater than.
1074*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/1xyyyy9e(v=vs.100)
_mm_cmpgt_ss(__m128 a,__m128 b)1075*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpgt_ss(__m128 a, __m128 b)
1076*35ffd701SAndroid Build Coastguard Worker {
1077*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_cmpgt_ps(a, b));
1078*35ffd701SAndroid Build Coastguard Worker }
1079*35ffd701SAndroid Build Coastguard Worker
1080*35ffd701SAndroid Build Coastguard Worker // Compares for less than or equal.
1081*35ffd701SAndroid Build Coastguard Worker //
1082*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 <= b0) ? 0xffffffff : 0x0
1083*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 <= b1) ? 0xffffffff : 0x0
1084*35ffd701SAndroid Build Coastguard Worker // r2 := (a2 <= b2) ? 0xffffffff : 0x0
1085*35ffd701SAndroid Build Coastguard Worker // r3 := (a3 <= b3) ? 0xffffffff : 0x0
1086*35ffd701SAndroid Build Coastguard Worker //
1087*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/1s75w83z(v=vs.100).aspx
_mm_cmple_ps(__m128 a,__m128 b)1088*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b)
1089*35ffd701SAndroid Build Coastguard Worker {
1090*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_u32(
1091*35ffd701SAndroid Build Coastguard Worker vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
1092*35ffd701SAndroid Build Coastguard Worker }
1093*35ffd701SAndroid Build Coastguard Worker
1094*35ffd701SAndroid Build Coastguard Worker // Compares for less than or equal.
1095*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/a7x0hbhw(v=vs.100)
_mm_cmple_ss(__m128 a,__m128 b)1096*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmple_ss(__m128 a, __m128 b)
1097*35ffd701SAndroid Build Coastguard Worker {
1098*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_cmple_ps(a, b));
1099*35ffd701SAndroid Build Coastguard Worker }
1100*35ffd701SAndroid Build Coastguard Worker
1101*35ffd701SAndroid Build Coastguard Worker // Compares for less than
1102*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/f330yhc8(v=vs.100).aspx
_mm_cmplt_ps(__m128 a,__m128 b)1103*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmplt_ps(__m128 a, __m128 b)
1104*35ffd701SAndroid Build Coastguard Worker {
1105*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_u32(
1106*35ffd701SAndroid Build Coastguard Worker vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
1107*35ffd701SAndroid Build Coastguard Worker }
1108*35ffd701SAndroid Build Coastguard Worker
1109*35ffd701SAndroid Build Coastguard Worker // Compares for less than
1110*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fy94wye7(v=vs.100)
_mm_cmplt_ss(__m128 a,__m128 b)1111*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmplt_ss(__m128 a, __m128 b)
1112*35ffd701SAndroid Build Coastguard Worker {
1113*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_cmplt_ps(a, b));
1114*35ffd701SAndroid Build Coastguard Worker }
1115*35ffd701SAndroid Build Coastguard Worker
1116*35ffd701SAndroid Build Coastguard Worker // Compares for inequality.
1117*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/sf44thbx(v=vs.100).aspx
_mm_cmpneq_ps(__m128 a,__m128 b)1118*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpneq_ps(__m128 a, __m128 b)
1119*35ffd701SAndroid Build Coastguard Worker {
1120*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_u32(vmvnq_u32(
1121*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))));
1122*35ffd701SAndroid Build Coastguard Worker }
1123*35ffd701SAndroid Build Coastguard Worker
1124*35ffd701SAndroid Build Coastguard Worker // Compares for inequality.
1125*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ekya8fh4(v=vs.100)
_mm_cmpneq_ss(__m128 a,__m128 b)1126*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpneq_ss(__m128 a, __m128 b)
1127*35ffd701SAndroid Build Coastguard Worker {
1128*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_cmpneq_ps(a, b));
1129*35ffd701SAndroid Build Coastguard Worker }
1130*35ffd701SAndroid Build Coastguard Worker
1131*35ffd701SAndroid Build Coastguard Worker // Compares for not greater than or equal.
1132*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/wsexys62(v=vs.100)
_mm_cmpnge_ps(__m128 a,__m128 b)1133*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpnge_ps(__m128 a, __m128 b)
1134*35ffd701SAndroid Build Coastguard Worker {
1135*35ffd701SAndroid Build Coastguard Worker return _mm_cmplt_ps(a, b);
1136*35ffd701SAndroid Build Coastguard Worker }
1137*35ffd701SAndroid Build Coastguard Worker
1138*35ffd701SAndroid Build Coastguard Worker // Compares for not greater than or equal.
1139*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fk2y80s8(v=vs.100)
_mm_cmpnge_ss(__m128 a,__m128 b)1140*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpnge_ss(__m128 a, __m128 b)
1141*35ffd701SAndroid Build Coastguard Worker {
1142*35ffd701SAndroid Build Coastguard Worker return _mm_cmplt_ss(a, b);
1143*35ffd701SAndroid Build Coastguard Worker }
1144*35ffd701SAndroid Build Coastguard Worker
1145*35ffd701SAndroid Build Coastguard Worker // Compares for not greater than.
1146*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/d0xh7w0s(v=vs.100)
_mm_cmpngt_ps(__m128 a,__m128 b)1147*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpngt_ps(__m128 a, __m128 b)
1148*35ffd701SAndroid Build Coastguard Worker {
1149*35ffd701SAndroid Build Coastguard Worker return _mm_cmple_ps(a, b);
1150*35ffd701SAndroid Build Coastguard Worker }
1151*35ffd701SAndroid Build Coastguard Worker
1152*35ffd701SAndroid Build Coastguard Worker // Compares for not greater than.
1153*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100)
_mm_cmpngt_ss(__m128 a,__m128 b)1154*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpngt_ss(__m128 a, __m128 b)
1155*35ffd701SAndroid Build Coastguard Worker {
1156*35ffd701SAndroid Build Coastguard Worker return _mm_cmple_ss(a, b);
1157*35ffd701SAndroid Build Coastguard Worker }
1158*35ffd701SAndroid Build Coastguard Worker
1159*35ffd701SAndroid Build Coastguard Worker // Compares for not less than or equal.
1160*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/6a330kxw(v=vs.100)
_mm_cmpnle_ps(__m128 a,__m128 b)1161*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpnle_ps(__m128 a, __m128 b)
1162*35ffd701SAndroid Build Coastguard Worker {
1163*35ffd701SAndroid Build Coastguard Worker return _mm_cmpgt_ps(a, b);
1164*35ffd701SAndroid Build Coastguard Worker }
1165*35ffd701SAndroid Build Coastguard Worker
1166*35ffd701SAndroid Build Coastguard Worker // Compares for not less than or equal.
1167*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100)
_mm_cmpnle_ss(__m128 a,__m128 b)1168*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpnle_ss(__m128 a, __m128 b)
1169*35ffd701SAndroid Build Coastguard Worker {
1170*35ffd701SAndroid Build Coastguard Worker return _mm_cmpgt_ss(a, b);
1171*35ffd701SAndroid Build Coastguard Worker }
1172*35ffd701SAndroid Build Coastguard Worker
1173*35ffd701SAndroid Build Coastguard Worker // Compares for not less than.
1174*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/4686bbdw(v=vs.100)
_mm_cmpnlt_ps(__m128 a,__m128 b)1175*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpnlt_ps(__m128 a, __m128 b)
1176*35ffd701SAndroid Build Coastguard Worker {
1177*35ffd701SAndroid Build Coastguard Worker return _mm_cmpge_ps(a, b);
1178*35ffd701SAndroid Build Coastguard Worker }
1179*35ffd701SAndroid Build Coastguard Worker
1180*35ffd701SAndroid Build Coastguard Worker // Compares for not less than.
1181*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/56b9z2wf(v=vs.100)
_mm_cmpnlt_ss(__m128 a,__m128 b)1182*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpnlt_ss(__m128 a, __m128 b)
1183*35ffd701SAndroid Build Coastguard Worker {
1184*35ffd701SAndroid Build Coastguard Worker return _mm_cmpge_ss(a, b);
1185*35ffd701SAndroid Build Coastguard Worker }
1186*35ffd701SAndroid Build Coastguard Worker
1187*35ffd701SAndroid Build Coastguard Worker // Compares the four 32-bit floats in a and b to check if any values are NaN.
1188*35ffd701SAndroid Build Coastguard Worker // Ordered compare between each value returns true for "orderable" and false for
1189*35ffd701SAndroid Build Coastguard Worker // "not orderable" (NaN).
1190*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx see
1191*35ffd701SAndroid Build Coastguard Worker // also:
1192*35ffd701SAndroid Build Coastguard Worker // http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean
1193*35ffd701SAndroid Build Coastguard Worker // http://stackoverflow.com/questions/29349621/neon-isnanval-intrinsics
_mm_cmpord_ps(__m128 a,__m128 b)1194*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpord_ps(__m128 a, __m128 b)
1195*35ffd701SAndroid Build Coastguard Worker {
1196*35ffd701SAndroid Build Coastguard Worker // Note: NEON does not have ordered compare builtin
1197*35ffd701SAndroid Build Coastguard Worker // Need to compare a eq a and b eq b to check for NaN
1198*35ffd701SAndroid Build Coastguard Worker // Do AND of results to get final
1199*35ffd701SAndroid Build Coastguard Worker uint32x4_t ceqaa =
1200*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a));
1201*35ffd701SAndroid Build Coastguard Worker uint32x4_t ceqbb =
1202*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b));
1203*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_u32(vandq_u32(ceqaa, ceqbb));
1204*35ffd701SAndroid Build Coastguard Worker }
1205*35ffd701SAndroid Build Coastguard Worker
1206*35ffd701SAndroid Build Coastguard Worker // Compares for ordered.
1207*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/343t62da(v=vs.100)
_mm_cmpord_ss(__m128 a,__m128 b)1208*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpord_ss(__m128 a, __m128 b)
1209*35ffd701SAndroid Build Coastguard Worker {
1210*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_cmpord_ps(a, b));
1211*35ffd701SAndroid Build Coastguard Worker }
1212*35ffd701SAndroid Build Coastguard Worker
1213*35ffd701SAndroid Build Coastguard Worker // Compares for unordered.
1214*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/khy6fk1t(v=vs.100)
_mm_cmpunord_ps(__m128 a,__m128 b)1215*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpunord_ps(__m128 a, __m128 b)
1216*35ffd701SAndroid Build Coastguard Worker {
1217*35ffd701SAndroid Build Coastguard Worker uint32x4_t f32a =
1218*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a));
1219*35ffd701SAndroid Build Coastguard Worker uint32x4_t f32b =
1220*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b));
1221*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_u32(vmvnq_u32(vandq_u32(f32a, f32b)));
1222*35ffd701SAndroid Build Coastguard Worker }
1223*35ffd701SAndroid Build Coastguard Worker
1224*35ffd701SAndroid Build Coastguard Worker // Compares for unordered.
1225*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2as2387b(v=vs.100)
_mm_cmpunord_ss(__m128 a,__m128 b)1226*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cmpunord_ss(__m128 a, __m128 b)
1227*35ffd701SAndroid Build Coastguard Worker {
1228*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_cmpunord_ps(a, b));
1229*35ffd701SAndroid Build Coastguard Worker }
1230*35ffd701SAndroid Build Coastguard Worker
1231*35ffd701SAndroid Build Coastguard Worker // Compares the lower single-precision floating point scalar values of a and b
1232*35ffd701SAndroid Build Coastguard Worker // using an equality operation. :
1233*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/93yx2h2b(v=vs.100).aspx
_mm_comieq_ss(__m128 a,__m128 b)1234*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comieq_ss(__m128 a, __m128 b)
1235*35ffd701SAndroid Build Coastguard Worker {
1236*35ffd701SAndroid Build Coastguard Worker // return vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a),
1237*35ffd701SAndroid Build Coastguard Worker // vreinterpretq_f32_m128(b)), 0);
1238*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_not_nan =
1239*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a));
1240*35ffd701SAndroid Build Coastguard Worker uint32x4_t b_not_nan =
1241*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b));
1242*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan);
1243*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_eq_b =
1244*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b));
1245*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_eq_b), 0) & 0x1;
1246*35ffd701SAndroid Build Coastguard Worker }
1247*35ffd701SAndroid Build Coastguard Worker
1248*35ffd701SAndroid Build Coastguard Worker // Compares the lower single-precision floating point scalar values of a and b
1249*35ffd701SAndroid Build Coastguard Worker // using a greater than or equal operation. :
1250*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/8t80des6(v=vs.100).aspx
_mm_comige_ss(__m128 a,__m128 b)1251*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comige_ss(__m128 a, __m128 b)
1252*35ffd701SAndroid Build Coastguard Worker {
1253*35ffd701SAndroid Build Coastguard Worker // return vgetq_lane_u32(vcgeq_f32(vreinterpretq_f32_m128(a),
1254*35ffd701SAndroid Build Coastguard Worker // vreinterpretq_f32_m128(b)), 0);
1255*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_not_nan =
1256*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a));
1257*35ffd701SAndroid Build Coastguard Worker uint32x4_t b_not_nan =
1258*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b));
1259*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan);
1260*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_ge_b =
1261*35ffd701SAndroid Build Coastguard Worker vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b));
1262*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_ge_b), 0) & 0x1;
1263*35ffd701SAndroid Build Coastguard Worker }
1264*35ffd701SAndroid Build Coastguard Worker
1265*35ffd701SAndroid Build Coastguard Worker // Compares the lower single-precision floating point scalar values of a and b
1266*35ffd701SAndroid Build Coastguard Worker // using a greater than operation. :
1267*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/b0738e0t(v=vs.100).aspx
_mm_comigt_ss(__m128 a,__m128 b)1268*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comigt_ss(__m128 a, __m128 b)
1269*35ffd701SAndroid Build Coastguard Worker {
1270*35ffd701SAndroid Build Coastguard Worker // return vgetq_lane_u32(vcgtq_f32(vreinterpretq_f32_m128(a),
1271*35ffd701SAndroid Build Coastguard Worker // vreinterpretq_f32_m128(b)), 0);
1272*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_not_nan =
1273*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a));
1274*35ffd701SAndroid Build Coastguard Worker uint32x4_t b_not_nan =
1275*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b));
1276*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan);
1277*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_gt_b =
1278*35ffd701SAndroid Build Coastguard Worker vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b));
1279*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_gt_b), 0) & 0x1;
1280*35ffd701SAndroid Build Coastguard Worker }
1281*35ffd701SAndroid Build Coastguard Worker
1282*35ffd701SAndroid Build Coastguard Worker // Compares the lower single-precision floating point scalar values of a and b
1283*35ffd701SAndroid Build Coastguard Worker // using a less than or equal operation. :
1284*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/1w4t7c57(v=vs.90).aspx
_mm_comile_ss(__m128 a,__m128 b)1285*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comile_ss(__m128 a, __m128 b)
1286*35ffd701SAndroid Build Coastguard Worker {
1287*35ffd701SAndroid Build Coastguard Worker // return vgetq_lane_u32(vcleq_f32(vreinterpretq_f32_m128(a),
1288*35ffd701SAndroid Build Coastguard Worker // vreinterpretq_f32_m128(b)), 0);
1289*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_not_nan =
1290*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a));
1291*35ffd701SAndroid Build Coastguard Worker uint32x4_t b_not_nan =
1292*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b));
1293*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan);
1294*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_le_b =
1295*35ffd701SAndroid Build Coastguard Worker vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b));
1296*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_le_b), 0) & 0x1;
1297*35ffd701SAndroid Build Coastguard Worker }
1298*35ffd701SAndroid Build Coastguard Worker
1299*35ffd701SAndroid Build Coastguard Worker // Compares the lower single-precision floating point scalar values of a and b
1300*35ffd701SAndroid Build Coastguard Worker // using a less than operation. :
1301*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/2kwe606b(v=vs.90).aspx Important
1302*35ffd701SAndroid Build Coastguard Worker // note!! The documentation on MSDN is incorrect! If either of the values is a
1303*35ffd701SAndroid Build Coastguard Worker // NAN the docs say you will get a one, but in fact, it will return a zero!!
_mm_comilt_ss(__m128 a,__m128 b)1304*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comilt_ss(__m128 a, __m128 b)
1305*35ffd701SAndroid Build Coastguard Worker {
1306*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_not_nan =
1307*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a));
1308*35ffd701SAndroid Build Coastguard Worker uint32x4_t b_not_nan =
1309*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b));
1310*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan);
1311*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_lt_b =
1312*35ffd701SAndroid Build Coastguard Worker vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b));
1313*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_lt_b), 0) & 0x1;
1314*35ffd701SAndroid Build Coastguard Worker }
1315*35ffd701SAndroid Build Coastguard Worker
1316*35ffd701SAndroid Build Coastguard Worker // Compares the lower single-precision floating point scalar values of a and b
1317*35ffd701SAndroid Build Coastguard Worker // using an inequality operation. :
1318*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/bafh5e0a(v=vs.90).aspx
_mm_comineq_ss(__m128 a,__m128 b)1319*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comineq_ss(__m128 a, __m128 b)
1320*35ffd701SAndroid Build Coastguard Worker {
1321*35ffd701SAndroid Build Coastguard Worker // return !vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a),
1322*35ffd701SAndroid Build Coastguard Worker // vreinterpretq_f32_m128(b)), 0);
1323*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_not_nan =
1324*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a));
1325*35ffd701SAndroid Build Coastguard Worker uint32x4_t b_not_nan =
1326*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b));
1327*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_or_b_nan = vmvnq_u32(vandq_u32(a_not_nan, b_not_nan));
1328*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_neq_b = vmvnq_u32(
1329*35ffd701SAndroid Build Coastguard Worker vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
1330*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u32(vorrq_u32(a_or_b_nan, a_neq_b), 0) & 0x1;
1331*35ffd701SAndroid Build Coastguard Worker }
1332*35ffd701SAndroid Build Coastguard Worker
1333*35ffd701SAndroid Build Coastguard Worker // Convert packed signed 32-bit integers in b to packed single-precision
1334*35ffd701SAndroid Build Coastguard Worker // (32-bit) floating-point elements, store the results in the lower 2 elements
1335*35ffd701SAndroid Build Coastguard Worker // of dst, and copy the upper 2 packed elements from a to the upper elements of
1336*35ffd701SAndroid Build Coastguard Worker // dst.
1337*35ffd701SAndroid Build Coastguard Worker //
1338*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_Int32_To_FP32(b[31:0])
1339*35ffd701SAndroid Build Coastguard Worker // dst[63:32] := Convert_Int32_To_FP32(b[63:32])
1340*35ffd701SAndroid Build Coastguard Worker // dst[95:64] := a[95:64]
1341*35ffd701SAndroid Build Coastguard Worker // dst[127:96] := a[127:96]
1342*35ffd701SAndroid Build Coastguard Worker //
1343*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_pi2ps
_mm_cvt_pi2ps(__m128 a,__m64 b)1344*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvt_pi2ps(__m128 a, __m64 b)
1345*35ffd701SAndroid Build Coastguard Worker {
1346*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1347*35ffd701SAndroid Build Coastguard Worker vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)),
1348*35ffd701SAndroid Build Coastguard Worker vget_high_f32(vreinterpretq_f32_m128(a))));
1349*35ffd701SAndroid Build Coastguard Worker }
1350*35ffd701SAndroid Build Coastguard Worker
1351*35ffd701SAndroid Build Coastguard Worker // Convert packed single-precision (32-bit) floating-point elements in a to
1352*35ffd701SAndroid Build Coastguard Worker // packed 32-bit integers, and store the results in dst.
1353*35ffd701SAndroid Build Coastguard Worker //
1354*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
1355*35ffd701SAndroid Build Coastguard Worker // i := 32*j
1356*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i])
1357*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1358*35ffd701SAndroid Build Coastguard Worker //
1359*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ps2pi
_mm_cvt_ps2pi(__m128 a)1360*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_cvt_ps2pi(__m128 a)
1361*35ffd701SAndroid Build Coastguard Worker {
1362*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
1363*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(
1364*35ffd701SAndroid Build Coastguard Worker vget_low_s32(vcvtnq_s32_f32(vrndiq_f32(vreinterpretq_f32_m128(a)))));
1365*35ffd701SAndroid Build Coastguard Worker #else
1366*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(vcvt_s32_f32(vget_low_f32(
1367*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(_mm_round_ps(a, _MM_FROUND_CUR_DIRECTION)))));
1368*35ffd701SAndroid Build Coastguard Worker #endif
1369*35ffd701SAndroid Build Coastguard Worker }
1370*35ffd701SAndroid Build Coastguard Worker
1371*35ffd701SAndroid Build Coastguard Worker // Convert the signed 32-bit integer b to a single-precision (32-bit)
1372*35ffd701SAndroid Build Coastguard Worker // floating-point element, store the result in the lower element of dst, and
1373*35ffd701SAndroid Build Coastguard Worker // copy the upper 3 packed elements from a to the upper elements of dst.
1374*35ffd701SAndroid Build Coastguard Worker //
1375*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_Int32_To_FP32(b[31:0])
1376*35ffd701SAndroid Build Coastguard Worker // dst[127:32] := a[127:32]
1377*35ffd701SAndroid Build Coastguard Worker //
1378*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_si2ss
_mm_cvt_si2ss(__m128 a,int b)1379*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvt_si2ss(__m128 a, int b)
1380*35ffd701SAndroid Build Coastguard Worker {
1381*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1382*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0));
1383*35ffd701SAndroid Build Coastguard Worker }
1384*35ffd701SAndroid Build Coastguard Worker
1385*35ffd701SAndroid Build Coastguard Worker // Convert the lower single-precision (32-bit) floating-point element in a to a
1386*35ffd701SAndroid Build Coastguard Worker // 32-bit integer, and store the result in dst.
1387*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ss2si
_mm_cvt_ss2si(__m128 a)1388*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_cvt_ss2si(__m128 a)
1389*35ffd701SAndroid Build Coastguard Worker {
1390*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
1391*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_s32(vcvtnq_s32_f32(vrndiq_f32(vreinterpretq_f32_m128(a))),
1392*35ffd701SAndroid Build Coastguard Worker 0);
1393*35ffd701SAndroid Build Coastguard Worker #else
1394*35ffd701SAndroid Build Coastguard Worker float32_t data = vgetq_lane_f32(
1395*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(_mm_round_ps(a, _MM_FROUND_CUR_DIRECTION)), 0);
1396*35ffd701SAndroid Build Coastguard Worker return (int32_t) data;
1397*35ffd701SAndroid Build Coastguard Worker #endif
1398*35ffd701SAndroid Build Coastguard Worker }
1399*35ffd701SAndroid Build Coastguard Worker
1400*35ffd701SAndroid Build Coastguard Worker // Convert packed 16-bit integers in a to packed single-precision (32-bit)
1401*35ffd701SAndroid Build Coastguard Worker // floating-point elements, and store the results in dst.
1402*35ffd701SAndroid Build Coastguard Worker //
1403*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
1404*35ffd701SAndroid Build Coastguard Worker // i := j*16
1405*35ffd701SAndroid Build Coastguard Worker // m := j*32
1406*35ffd701SAndroid Build Coastguard Worker // dst[m+31:m] := Convert_Int16_To_FP32(a[i+15:i])
1407*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1408*35ffd701SAndroid Build Coastguard Worker //
1409*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi16_ps
_mm_cvtpi16_ps(__m64 a)1410*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtpi16_ps(__m64 a)
1411*35ffd701SAndroid Build Coastguard Worker {
1412*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1413*35ffd701SAndroid Build Coastguard Worker vcvtq_f32_s32(vmovl_s16(vreinterpret_s16_m64(a))));
1414*35ffd701SAndroid Build Coastguard Worker }
1415*35ffd701SAndroid Build Coastguard Worker
1416*35ffd701SAndroid Build Coastguard Worker // Convert packed 32-bit integers in b to packed single-precision (32-bit)
1417*35ffd701SAndroid Build Coastguard Worker // floating-point elements, store the results in the lower 2 elements of dst,
1418*35ffd701SAndroid Build Coastguard Worker // and copy the upper 2 packed elements from a to the upper elements of dst.
1419*35ffd701SAndroid Build Coastguard Worker //
1420*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_Int32_To_FP32(b[31:0])
1421*35ffd701SAndroid Build Coastguard Worker // dst[63:32] := Convert_Int32_To_FP32(b[63:32])
1422*35ffd701SAndroid Build Coastguard Worker // dst[95:64] := a[95:64]
1423*35ffd701SAndroid Build Coastguard Worker // dst[127:96] := a[127:96]
1424*35ffd701SAndroid Build Coastguard Worker //
1425*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_ps
_mm_cvtpi32_ps(__m128 a,__m64 b)1426*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtpi32_ps(__m128 a, __m64 b)
1427*35ffd701SAndroid Build Coastguard Worker {
1428*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1429*35ffd701SAndroid Build Coastguard Worker vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)),
1430*35ffd701SAndroid Build Coastguard Worker vget_high_f32(vreinterpretq_f32_m128(a))));
1431*35ffd701SAndroid Build Coastguard Worker }
1432*35ffd701SAndroid Build Coastguard Worker
1433*35ffd701SAndroid Build Coastguard Worker // Convert packed signed 32-bit integers in a to packed single-precision
1434*35ffd701SAndroid Build Coastguard Worker // (32-bit) floating-point elements, store the results in the lower 2 elements
1435*35ffd701SAndroid Build Coastguard Worker // of dst, then covert the packed signed 32-bit integers in b to
1436*35ffd701SAndroid Build Coastguard Worker // single-precision (32-bit) floating-point element, and store the results in
1437*35ffd701SAndroid Build Coastguard Worker // the upper 2 elements of dst.
1438*35ffd701SAndroid Build Coastguard Worker //
1439*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_Int32_To_FP32(a[31:0])
1440*35ffd701SAndroid Build Coastguard Worker // dst[63:32] := Convert_Int32_To_FP32(a[63:32])
1441*35ffd701SAndroid Build Coastguard Worker // dst[95:64] := Convert_Int32_To_FP32(b[31:0])
1442*35ffd701SAndroid Build Coastguard Worker // dst[127:96] := Convert_Int32_To_FP32(b[63:32])
1443*35ffd701SAndroid Build Coastguard Worker //
1444*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32x2_ps
_mm_cvtpi32x2_ps(__m64 a,__m64 b)1445*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtpi32x2_ps(__m64 a, __m64 b)
1446*35ffd701SAndroid Build Coastguard Worker {
1447*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcvtq_f32_s32(
1448*35ffd701SAndroid Build Coastguard Worker vcombine_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b))));
1449*35ffd701SAndroid Build Coastguard Worker }
1450*35ffd701SAndroid Build Coastguard Worker
1451*35ffd701SAndroid Build Coastguard Worker // Convert the lower packed 8-bit integers in a to packed single-precision
1452*35ffd701SAndroid Build Coastguard Worker // (32-bit) floating-point elements, and store the results in dst.
1453*35ffd701SAndroid Build Coastguard Worker //
1454*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
1455*35ffd701SAndroid Build Coastguard Worker // i := j*8
1456*35ffd701SAndroid Build Coastguard Worker // m := j*32
1457*35ffd701SAndroid Build Coastguard Worker // dst[m+31:m] := Convert_Int8_To_FP32(a[i+7:i])
1458*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1459*35ffd701SAndroid Build Coastguard Worker //
1460*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi8_ps
_mm_cvtpi8_ps(__m64 a)1461*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtpi8_ps(__m64 a)
1462*35ffd701SAndroid Build Coastguard Worker {
1463*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcvtq_f32_s32(
1464*35ffd701SAndroid Build Coastguard Worker vmovl_s16(vget_low_s16(vmovl_s8(vreinterpret_s8_m64(a))))));
1465*35ffd701SAndroid Build Coastguard Worker }
1466*35ffd701SAndroid Build Coastguard Worker
1467*35ffd701SAndroid Build Coastguard Worker // Convert packed single-precision (32-bit) floating-point elements in a to
1468*35ffd701SAndroid Build Coastguard Worker // packed 16-bit integers, and store the results in dst. Note: this intrinsic
1469*35ffd701SAndroid Build Coastguard Worker // will generate 0x7FFF, rather than 0x8000, for input values between 0x7FFF and
1470*35ffd701SAndroid Build Coastguard Worker // 0x7FFFFFFF.
1471*35ffd701SAndroid Build Coastguard Worker //
1472*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi16
_mm_cvtps_pi16(__m128 a)1473*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_cvtps_pi16(__m128 a)
1474*35ffd701SAndroid Build Coastguard Worker {
1475*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s16(
1476*35ffd701SAndroid Build Coastguard Worker vmovn_s32(vreinterpretq_s32_m128i(_mm_cvtps_epi32(a))));
1477*35ffd701SAndroid Build Coastguard Worker }
1478*35ffd701SAndroid Build Coastguard Worker
1479*35ffd701SAndroid Build Coastguard Worker // Convert packed single-precision (32-bit) floating-point elements in a to
1480*35ffd701SAndroid Build Coastguard Worker // packed 32-bit integers, and store the results in dst.
1481*35ffd701SAndroid Build Coastguard Worker //
1482*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
1483*35ffd701SAndroid Build Coastguard Worker // i := 32*j
1484*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i])
1485*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1486*35ffd701SAndroid Build Coastguard Worker //
1487*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi32
1488*35ffd701SAndroid Build Coastguard Worker #define _mm_cvtps_pi32(a) _mm_cvt_ps2pi(a)
1489*35ffd701SAndroid Build Coastguard Worker
1490*35ffd701SAndroid Build Coastguard Worker // Convert packed unsigned 16-bit integers in a to packed single-precision
1491*35ffd701SAndroid Build Coastguard Worker // (32-bit) floating-point elements, and store the results in dst.
1492*35ffd701SAndroid Build Coastguard Worker //
1493*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
1494*35ffd701SAndroid Build Coastguard Worker // i := j*16
1495*35ffd701SAndroid Build Coastguard Worker // m := j*32
1496*35ffd701SAndroid Build Coastguard Worker // dst[m+31:m] := Convert_UInt16_To_FP32(a[i+15:i])
1497*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1498*35ffd701SAndroid Build Coastguard Worker //
1499*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu16_ps
_mm_cvtpu16_ps(__m64 a)1500*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtpu16_ps(__m64 a)
1501*35ffd701SAndroid Build Coastguard Worker {
1502*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1503*35ffd701SAndroid Build Coastguard Worker vcvtq_f32_u32(vmovl_u16(vreinterpret_u16_m64(a))));
1504*35ffd701SAndroid Build Coastguard Worker }
1505*35ffd701SAndroid Build Coastguard Worker
1506*35ffd701SAndroid Build Coastguard Worker // Convert the lower packed unsigned 8-bit integers in a to packed
1507*35ffd701SAndroid Build Coastguard Worker // single-precision (32-bit) floating-point elements, and store the results in
1508*35ffd701SAndroid Build Coastguard Worker // dst.
1509*35ffd701SAndroid Build Coastguard Worker //
1510*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
1511*35ffd701SAndroid Build Coastguard Worker // i := j*8
1512*35ffd701SAndroid Build Coastguard Worker // m := j*32
1513*35ffd701SAndroid Build Coastguard Worker // dst[m+31:m] := Convert_UInt8_To_FP32(a[i+7:i])
1514*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1515*35ffd701SAndroid Build Coastguard Worker //
1516*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu8_ps
_mm_cvtpu8_ps(__m64 a)1517*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtpu8_ps(__m64 a)
1518*35ffd701SAndroid Build Coastguard Worker {
1519*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcvtq_f32_u32(
1520*35ffd701SAndroid Build Coastguard Worker vmovl_u16(vget_low_u16(vmovl_u8(vreinterpret_u8_m64(a))))));
1521*35ffd701SAndroid Build Coastguard Worker }
1522*35ffd701SAndroid Build Coastguard Worker
1523*35ffd701SAndroid Build Coastguard Worker // Convert the signed 32-bit integer b to a single-precision (32-bit)
1524*35ffd701SAndroid Build Coastguard Worker // floating-point element, store the result in the lower element of dst, and
1525*35ffd701SAndroid Build Coastguard Worker // copy the upper 3 packed elements from a to the upper elements of dst.
1526*35ffd701SAndroid Build Coastguard Worker //
1527*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_Int32_To_FP32(b[31:0])
1528*35ffd701SAndroid Build Coastguard Worker // dst[127:32] := a[127:32]
1529*35ffd701SAndroid Build Coastguard Worker //
1530*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_ss
1531*35ffd701SAndroid Build Coastguard Worker #define _mm_cvtsi32_ss(a, b) _mm_cvt_si2ss(a, b)
1532*35ffd701SAndroid Build Coastguard Worker
1533*35ffd701SAndroid Build Coastguard Worker // Convert the signed 64-bit integer b to a single-precision (32-bit)
1534*35ffd701SAndroid Build Coastguard Worker // floating-point element, store the result in the lower element of dst, and
1535*35ffd701SAndroid Build Coastguard Worker // copy the upper 3 packed elements from a to the upper elements of dst.
1536*35ffd701SAndroid Build Coastguard Worker //
1537*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_Int64_To_FP32(b[63:0])
1538*35ffd701SAndroid Build Coastguard Worker // dst[127:32] := a[127:32]
1539*35ffd701SAndroid Build Coastguard Worker //
1540*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_ss
_mm_cvtsi64_ss(__m128 a,int64_t b)1541*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtsi64_ss(__m128 a, int64_t b)
1542*35ffd701SAndroid Build Coastguard Worker {
1543*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1544*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0));
1545*35ffd701SAndroid Build Coastguard Worker }
1546*35ffd701SAndroid Build Coastguard Worker
1547*35ffd701SAndroid Build Coastguard Worker // Copy the lower single-precision (32-bit) floating-point element of a to dst.
1548*35ffd701SAndroid Build Coastguard Worker //
1549*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := a[31:0]
1550*35ffd701SAndroid Build Coastguard Worker //
1551*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_f32
_mm_cvtss_f32(__m128 a)1552*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE float _mm_cvtss_f32(__m128 a)
1553*35ffd701SAndroid Build Coastguard Worker {
1554*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_f32(vreinterpretq_f32_m128(a), 0);
1555*35ffd701SAndroid Build Coastguard Worker }
1556*35ffd701SAndroid Build Coastguard Worker
1557*35ffd701SAndroid Build Coastguard Worker // Convert the lower single-precision (32-bit) floating-point element in a to a
1558*35ffd701SAndroid Build Coastguard Worker // 32-bit integer, and store the result in dst.
1559*35ffd701SAndroid Build Coastguard Worker //
1560*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_FP32_To_Int32(a[31:0])
1561*35ffd701SAndroid Build Coastguard Worker //
1562*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si32
1563*35ffd701SAndroid Build Coastguard Worker #define _mm_cvtss_si32(a) _mm_cvt_ss2si(a)
1564*35ffd701SAndroid Build Coastguard Worker
1565*35ffd701SAndroid Build Coastguard Worker // Convert the lower single-precision (32-bit) floating-point element in a to a
1566*35ffd701SAndroid Build Coastguard Worker // 64-bit integer, and store the result in dst.
1567*35ffd701SAndroid Build Coastguard Worker //
1568*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := Convert_FP32_To_Int64(a[31:0])
1569*35ffd701SAndroid Build Coastguard Worker //
1570*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si64
_mm_cvtss_si64(__m128 a)1571*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int64_t _mm_cvtss_si64(__m128 a)
1572*35ffd701SAndroid Build Coastguard Worker {
1573*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
1574*35ffd701SAndroid Build Coastguard Worker return (int64_t) vgetq_lane_f32(vrndiq_f32(vreinterpretq_f32_m128(a)), 0);
1575*35ffd701SAndroid Build Coastguard Worker #else
1576*35ffd701SAndroid Build Coastguard Worker float32_t data = vgetq_lane_f32(
1577*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(_mm_round_ps(a, _MM_FROUND_CUR_DIRECTION)), 0);
1578*35ffd701SAndroid Build Coastguard Worker return (int64_t) data;
1579*35ffd701SAndroid Build Coastguard Worker #endif
1580*35ffd701SAndroid Build Coastguard Worker }
1581*35ffd701SAndroid Build Coastguard Worker
1582*35ffd701SAndroid Build Coastguard Worker // Convert packed single-precision (32-bit) floating-point elements in a to
1583*35ffd701SAndroid Build Coastguard Worker // packed 32-bit integers with truncation, and store the results in dst.
1584*35ffd701SAndroid Build Coastguard Worker //
1585*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
1586*35ffd701SAndroid Build Coastguard Worker // i := 32*j
1587*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i])
1588*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1589*35ffd701SAndroid Build Coastguard Worker //
1590*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ps2pi
_mm_cvtt_ps2pi(__m128 a)1591*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_cvtt_ps2pi(__m128 a)
1592*35ffd701SAndroid Build Coastguard Worker {
1593*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(
1594*35ffd701SAndroid Build Coastguard Worker vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a))));
1595*35ffd701SAndroid Build Coastguard Worker }
1596*35ffd701SAndroid Build Coastguard Worker
1597*35ffd701SAndroid Build Coastguard Worker // Convert the lower single-precision (32-bit) floating-point element in a to a
1598*35ffd701SAndroid Build Coastguard Worker // 32-bit integer with truncation, and store the result in dst.
1599*35ffd701SAndroid Build Coastguard Worker //
1600*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0])
1601*35ffd701SAndroid Build Coastguard Worker //
1602*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ss2si
_mm_cvtt_ss2si(__m128 a)1603*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_cvtt_ss2si(__m128 a)
1604*35ffd701SAndroid Build Coastguard Worker {
1605*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)), 0);
1606*35ffd701SAndroid Build Coastguard Worker }
1607*35ffd701SAndroid Build Coastguard Worker
1608*35ffd701SAndroid Build Coastguard Worker // Convert packed single-precision (32-bit) floating-point elements in a to
1609*35ffd701SAndroid Build Coastguard Worker // packed 32-bit integers with truncation, and store the results in dst.
1610*35ffd701SAndroid Build Coastguard Worker //
1611*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
1612*35ffd701SAndroid Build Coastguard Worker // i := 32*j
1613*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i])
1614*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1615*35ffd701SAndroid Build Coastguard Worker //
1616*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttps_pi32
1617*35ffd701SAndroid Build Coastguard Worker #define _mm_cvttps_pi32(a) _mm_cvtt_ps2pi(a)
1618*35ffd701SAndroid Build Coastguard Worker
1619*35ffd701SAndroid Build Coastguard Worker // Convert the lower single-precision (32-bit) floating-point element in a to a
1620*35ffd701SAndroid Build Coastguard Worker // 32-bit integer with truncation, and store the result in dst.
1621*35ffd701SAndroid Build Coastguard Worker //
1622*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0])
1623*35ffd701SAndroid Build Coastguard Worker //
1624*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si32
1625*35ffd701SAndroid Build Coastguard Worker #define _mm_cvttss_si32(a) _mm_cvtt_ss2si(a)
1626*35ffd701SAndroid Build Coastguard Worker
1627*35ffd701SAndroid Build Coastguard Worker // Convert the lower single-precision (32-bit) floating-point element in a to a
1628*35ffd701SAndroid Build Coastguard Worker // 64-bit integer with truncation, and store the result in dst.
1629*35ffd701SAndroid Build Coastguard Worker //
1630*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := Convert_FP32_To_Int64_Truncate(a[31:0])
1631*35ffd701SAndroid Build Coastguard Worker //
1632*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si64
_mm_cvttss_si64(__m128 a)1633*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int64_t _mm_cvttss_si64(__m128 a)
1634*35ffd701SAndroid Build Coastguard Worker {
1635*35ffd701SAndroid Build Coastguard Worker return (int64_t) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0);
1636*35ffd701SAndroid Build Coastguard Worker }
1637*35ffd701SAndroid Build Coastguard Worker
1638*35ffd701SAndroid Build Coastguard Worker // Divides the four single-precision, floating-point values of a and b.
1639*35ffd701SAndroid Build Coastguard Worker //
1640*35ffd701SAndroid Build Coastguard Worker // r0 := a0 / b0
1641*35ffd701SAndroid Build Coastguard Worker // r1 := a1 / b1
1642*35ffd701SAndroid Build Coastguard Worker // r2 := a2 / b2
1643*35ffd701SAndroid Build Coastguard Worker // r3 := a3 / b3
1644*35ffd701SAndroid Build Coastguard Worker //
1645*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/edaw8147(v=vs.100).aspx
_mm_div_ps(__m128 a,__m128 b)1646*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b)
1647*35ffd701SAndroid Build Coastguard Worker {
1648*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__) && !SSE2NEON_PRECISE_DIV
1649*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1650*35ffd701SAndroid Build Coastguard Worker vdivq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
1651*35ffd701SAndroid Build Coastguard Worker #else
1652*35ffd701SAndroid Build Coastguard Worker float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(b));
1653*35ffd701SAndroid Build Coastguard Worker recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b)));
1654*35ffd701SAndroid Build Coastguard Worker #if SSE2NEON_PRECISE_DIV
1655*35ffd701SAndroid Build Coastguard Worker // Additional Netwon-Raphson iteration for accuracy
1656*35ffd701SAndroid Build Coastguard Worker recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b)));
1657*35ffd701SAndroid Build Coastguard Worker #endif
1658*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(a), recip));
1659*35ffd701SAndroid Build Coastguard Worker #endif
1660*35ffd701SAndroid Build Coastguard Worker }
1661*35ffd701SAndroid Build Coastguard Worker
1662*35ffd701SAndroid Build Coastguard Worker // Divides the scalar single-precision floating point value of a by b.
1663*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/4y73xa49(v=vs.100).aspx
_mm_div_ss(__m128 a,__m128 b)1664*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b)
1665*35ffd701SAndroid Build Coastguard Worker {
1666*35ffd701SAndroid Build Coastguard Worker float32_t value =
1667*35ffd701SAndroid Build Coastguard Worker vgetq_lane_f32(vreinterpretq_f32_m128(_mm_div_ps(a, b)), 0);
1668*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1669*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0));
1670*35ffd701SAndroid Build Coastguard Worker }
1671*35ffd701SAndroid Build Coastguard Worker
1672*35ffd701SAndroid Build Coastguard Worker // Extract a 16-bit integer from a, selected with imm8, and store the result in
1673*35ffd701SAndroid Build Coastguard Worker // the lower element of dst.
1674*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_extract_pi16
1675*35ffd701SAndroid Build Coastguard Worker #define _mm_extract_pi16(a, imm) \
1676*35ffd701SAndroid Build Coastguard Worker (int32_t) vget_lane_u16(vreinterpret_u16_m64(a), (imm))
1677*35ffd701SAndroid Build Coastguard Worker
1678*35ffd701SAndroid Build Coastguard Worker // Free aligned memory that was allocated with _mm_malloc.
1679*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_free
_mm_free(void * addr)1680*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_free(void *addr)
1681*35ffd701SAndroid Build Coastguard Worker {
1682*35ffd701SAndroid Build Coastguard Worker free(addr);
1683*35ffd701SAndroid Build Coastguard Worker }
1684*35ffd701SAndroid Build Coastguard Worker
1685*35ffd701SAndroid Build Coastguard Worker // Macro: Get the rounding mode bits from the MXCSR control and status register.
1686*35ffd701SAndroid Build Coastguard Worker // The rounding mode may contain any of the following flags: _MM_ROUND_NEAREST,
1687*35ffd701SAndroid Build Coastguard Worker // _MM_ROUND_DOWN, _MM_ROUND_UP, _MM_ROUND_TOWARD_ZERO
1688*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_GET_ROUNDING_MODE
_MM_GET_ROUNDING_MODE()1689*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE()
1690*35ffd701SAndroid Build Coastguard Worker {
1691*35ffd701SAndroid Build Coastguard Worker union {
1692*35ffd701SAndroid Build Coastguard Worker fpcr_bitfield field;
1693*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
1694*35ffd701SAndroid Build Coastguard Worker uint64_t value;
1695*35ffd701SAndroid Build Coastguard Worker #else
1696*35ffd701SAndroid Build Coastguard Worker uint32_t value;
1697*35ffd701SAndroid Build Coastguard Worker #endif
1698*35ffd701SAndroid Build Coastguard Worker } r;
1699*35ffd701SAndroid Build Coastguard Worker
1700*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
1701*35ffd701SAndroid Build Coastguard Worker asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */
1702*35ffd701SAndroid Build Coastguard Worker #else
1703*35ffd701SAndroid Build Coastguard Worker asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */
1704*35ffd701SAndroid Build Coastguard Worker #endif
1705*35ffd701SAndroid Build Coastguard Worker
1706*35ffd701SAndroid Build Coastguard Worker if (r.field.bit22) {
1707*35ffd701SAndroid Build Coastguard Worker return r.field.bit23 ? _MM_ROUND_TOWARD_ZERO : _MM_ROUND_UP;
1708*35ffd701SAndroid Build Coastguard Worker } else {
1709*35ffd701SAndroid Build Coastguard Worker return r.field.bit23 ? _MM_ROUND_DOWN : _MM_ROUND_NEAREST;
1710*35ffd701SAndroid Build Coastguard Worker }
1711*35ffd701SAndroid Build Coastguard Worker }
1712*35ffd701SAndroid Build Coastguard Worker
1713*35ffd701SAndroid Build Coastguard Worker // Copy a to dst, and insert the 16-bit integer i into dst at the location
1714*35ffd701SAndroid Build Coastguard Worker // specified by imm8.
1715*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_insert_pi16
1716*35ffd701SAndroid Build Coastguard Worker #define _mm_insert_pi16(a, b, imm) \
1717*35ffd701SAndroid Build Coastguard Worker __extension__({ \
1718*35ffd701SAndroid Build Coastguard Worker vreinterpret_m64_s16( \
1719*35ffd701SAndroid Build Coastguard Worker vset_lane_s16((b), vreinterpret_s16_m64(a), (imm))); \
1720*35ffd701SAndroid Build Coastguard Worker })
1721*35ffd701SAndroid Build Coastguard Worker
1722*35ffd701SAndroid Build Coastguard Worker // Loads four single-precision, floating-point values.
1723*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/zzd50xxt(v=vs.100).aspx
_mm_load_ps(const float * p)1724*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_load_ps(const float *p)
1725*35ffd701SAndroid Build Coastguard Worker {
1726*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vld1q_f32(p));
1727*35ffd701SAndroid Build Coastguard Worker }
1728*35ffd701SAndroid Build Coastguard Worker
1729*35ffd701SAndroid Build Coastguard Worker // Load a single-precision (32-bit) floating-point element from memory into all
1730*35ffd701SAndroid Build Coastguard Worker // elements of dst.
1731*35ffd701SAndroid Build Coastguard Worker //
1732*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := MEM[mem_addr+31:mem_addr]
1733*35ffd701SAndroid Build Coastguard Worker // dst[63:32] := MEM[mem_addr+31:mem_addr]
1734*35ffd701SAndroid Build Coastguard Worker // dst[95:64] := MEM[mem_addr+31:mem_addr]
1735*35ffd701SAndroid Build Coastguard Worker // dst[127:96] := MEM[mem_addr+31:mem_addr]
1736*35ffd701SAndroid Build Coastguard Worker //
1737*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_ps1
1738*35ffd701SAndroid Build Coastguard Worker #define _mm_load_ps1 _mm_load1_ps
1739*35ffd701SAndroid Build Coastguard Worker
1740*35ffd701SAndroid Build Coastguard Worker // Loads an single - precision, floating - point value into the low word and
1741*35ffd701SAndroid Build Coastguard Worker // clears the upper three words.
1742*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/548bb9h4%28v=vs.90%29.aspx
_mm_load_ss(const float * p)1743*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_load_ss(const float *p)
1744*35ffd701SAndroid Build Coastguard Worker {
1745*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vsetq_lane_f32(*p, vdupq_n_f32(0), 0));
1746*35ffd701SAndroid Build Coastguard Worker }
1747*35ffd701SAndroid Build Coastguard Worker
1748*35ffd701SAndroid Build Coastguard Worker // Loads a single single-precision, floating-point value, copying it into all
1749*35ffd701SAndroid Build Coastguard Worker // four words
1750*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/5cdkf716(v=vs.100).aspx
_mm_load1_ps(const float * p)1751*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_load1_ps(const float *p)
1752*35ffd701SAndroid Build Coastguard Worker {
1753*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vld1q_dup_f32(p));
1754*35ffd701SAndroid Build Coastguard Worker }
1755*35ffd701SAndroid Build Coastguard Worker
1756*35ffd701SAndroid Build Coastguard Worker // Sets the upper two single-precision, floating-point values with 64
1757*35ffd701SAndroid Build Coastguard Worker // bits of data loaded from the address p; the lower two values are passed
1758*35ffd701SAndroid Build Coastguard Worker // through from a.
1759*35ffd701SAndroid Build Coastguard Worker //
1760*35ffd701SAndroid Build Coastguard Worker // r0 := a0
1761*35ffd701SAndroid Build Coastguard Worker // r1 := a1
1762*35ffd701SAndroid Build Coastguard Worker // r2 := *p0
1763*35ffd701SAndroid Build Coastguard Worker // r3 := *p1
1764*35ffd701SAndroid Build Coastguard Worker //
1765*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/w92wta0x(v%3dvs.100).aspx
_mm_loadh_pi(__m128 a,__m64 const * p)1766*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_loadh_pi(__m128 a, __m64 const *p)
1767*35ffd701SAndroid Build Coastguard Worker {
1768*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1769*35ffd701SAndroid Build Coastguard Worker vcombine_f32(vget_low_f32(a), vld1_f32((const float32_t *) p)));
1770*35ffd701SAndroid Build Coastguard Worker }
1771*35ffd701SAndroid Build Coastguard Worker
1772*35ffd701SAndroid Build Coastguard Worker // Sets the lower two single-precision, floating-point values with 64
1773*35ffd701SAndroid Build Coastguard Worker // bits of data loaded from the address p; the upper two values are passed
1774*35ffd701SAndroid Build Coastguard Worker // through from a.
1775*35ffd701SAndroid Build Coastguard Worker //
1776*35ffd701SAndroid Build Coastguard Worker // Return Value
1777*35ffd701SAndroid Build Coastguard Worker // r0 := *p0
1778*35ffd701SAndroid Build Coastguard Worker // r1 := *p1
1779*35ffd701SAndroid Build Coastguard Worker // r2 := a2
1780*35ffd701SAndroid Build Coastguard Worker // r3 := a3
1781*35ffd701SAndroid Build Coastguard Worker //
1782*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/s57cyak2(v=vs.100).aspx
_mm_loadl_pi(__m128 a,__m64 const * p)1783*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_loadl_pi(__m128 a, __m64 const *p)
1784*35ffd701SAndroid Build Coastguard Worker {
1785*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1786*35ffd701SAndroid Build Coastguard Worker vcombine_f32(vld1_f32((const float32_t *) p), vget_high_f32(a)));
1787*35ffd701SAndroid Build Coastguard Worker }
1788*35ffd701SAndroid Build Coastguard Worker
1789*35ffd701SAndroid Build Coastguard Worker // Load 4 single-precision (32-bit) floating-point elements from memory into dst
1790*35ffd701SAndroid Build Coastguard Worker // in reverse order. mem_addr must be aligned on a 16-byte boundary or a
1791*35ffd701SAndroid Build Coastguard Worker // general-protection exception may be generated.
1792*35ffd701SAndroid Build Coastguard Worker //
1793*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := MEM[mem_addr+127:mem_addr+96]
1794*35ffd701SAndroid Build Coastguard Worker // dst[63:32] := MEM[mem_addr+95:mem_addr+64]
1795*35ffd701SAndroid Build Coastguard Worker // dst[95:64] := MEM[mem_addr+63:mem_addr+32]
1796*35ffd701SAndroid Build Coastguard Worker // dst[127:96] := MEM[mem_addr+31:mem_addr]
1797*35ffd701SAndroid Build Coastguard Worker //
1798*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_ps
_mm_loadr_ps(const float * p)1799*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_loadr_ps(const float *p)
1800*35ffd701SAndroid Build Coastguard Worker {
1801*35ffd701SAndroid Build Coastguard Worker float32x4_t v = vrev64q_f32(vld1q_f32(p));
1802*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vextq_f32(v, v, 2));
1803*35ffd701SAndroid Build Coastguard Worker }
1804*35ffd701SAndroid Build Coastguard Worker
1805*35ffd701SAndroid Build Coastguard Worker // Loads four single-precision, floating-point values.
1806*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/x1b16s7z%28v=vs.90%29.aspx
_mm_loadu_ps(const float * p)1807*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_loadu_ps(const float *p)
1808*35ffd701SAndroid Build Coastguard Worker {
1809*35ffd701SAndroid Build Coastguard Worker // for neon, alignment doesn't matter, so _mm_load_ps and _mm_loadu_ps are
1810*35ffd701SAndroid Build Coastguard Worker // equivalent for neon
1811*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vld1q_f32(p));
1812*35ffd701SAndroid Build Coastguard Worker }
1813*35ffd701SAndroid Build Coastguard Worker
1814*35ffd701SAndroid Build Coastguard Worker // Load unaligned 16-bit integer from memory into the first element of dst.
1815*35ffd701SAndroid Build Coastguard Worker //
1816*35ffd701SAndroid Build Coastguard Worker // dst[15:0] := MEM[mem_addr+15:mem_addr]
1817*35ffd701SAndroid Build Coastguard Worker // dst[MAX:16] := 0
1818*35ffd701SAndroid Build Coastguard Worker //
1819*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si16
_mm_loadu_si16(const void * p)1820*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_loadu_si16(const void *p)
1821*35ffd701SAndroid Build Coastguard Worker {
1822*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
1823*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s16(*(const int16_t *) p, vdupq_n_s16(0), 0));
1824*35ffd701SAndroid Build Coastguard Worker }
1825*35ffd701SAndroid Build Coastguard Worker
1826*35ffd701SAndroid Build Coastguard Worker // Load unaligned 64-bit integer from memory into the first element of dst.
1827*35ffd701SAndroid Build Coastguard Worker //
1828*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := MEM[mem_addr+63:mem_addr]
1829*35ffd701SAndroid Build Coastguard Worker // dst[MAX:64] := 0
1830*35ffd701SAndroid Build Coastguard Worker //
1831*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si64
_mm_loadu_si64(const void * p)1832*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_loadu_si64(const void *p)
1833*35ffd701SAndroid Build Coastguard Worker {
1834*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(
1835*35ffd701SAndroid Build Coastguard Worker vcombine_s64(vld1_s64((const int64_t *) p), vdup_n_s64(0)));
1836*35ffd701SAndroid Build Coastguard Worker }
1837*35ffd701SAndroid Build Coastguard Worker
1838*35ffd701SAndroid Build Coastguard Worker // Allocate aligned blocks of memory.
1839*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/en-us/
1840*35ffd701SAndroid Build Coastguard Worker // cpp-compiler-developer-guide-and-reference-allocating-and-freeing-aligned-memory-blocks
_mm_malloc(size_t size,size_t align)1841*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void *_mm_malloc(size_t size, size_t align)
1842*35ffd701SAndroid Build Coastguard Worker {
1843*35ffd701SAndroid Build Coastguard Worker void *ptr;
1844*35ffd701SAndroid Build Coastguard Worker if (align == 1)
1845*35ffd701SAndroid Build Coastguard Worker return malloc(size);
1846*35ffd701SAndroid Build Coastguard Worker if (align == 2 || (sizeof(void *) == 8 && align == 4))
1847*35ffd701SAndroid Build Coastguard Worker align = sizeof(void *);
1848*35ffd701SAndroid Build Coastguard Worker if (!posix_memalign(&ptr, align, size))
1849*35ffd701SAndroid Build Coastguard Worker return ptr;
1850*35ffd701SAndroid Build Coastguard Worker return NULL;
1851*35ffd701SAndroid Build Coastguard Worker }
1852*35ffd701SAndroid Build Coastguard Worker
1853*35ffd701SAndroid Build Coastguard Worker // Conditionally store 8-bit integer elements from a into memory using mask
1854*35ffd701SAndroid Build Coastguard Worker // (elements are not stored when the highest bit is not set in the corresponding
1855*35ffd701SAndroid Build Coastguard Worker // element) and a non-temporal memory hint.
1856*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskmove_si64
_mm_maskmove_si64(__m64 a,__m64 mask,char * mem_addr)1857*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_maskmove_si64(__m64 a, __m64 mask, char *mem_addr)
1858*35ffd701SAndroid Build Coastguard Worker {
1859*35ffd701SAndroid Build Coastguard Worker int8x8_t shr_mask = vshr_n_s8(vreinterpret_s8_m64(mask), 7);
1860*35ffd701SAndroid Build Coastguard Worker __m128 b = _mm_load_ps((const float *) mem_addr);
1861*35ffd701SAndroid Build Coastguard Worker int8x8_t masked =
1862*35ffd701SAndroid Build Coastguard Worker vbsl_s8(vreinterpret_u8_s8(shr_mask), vreinterpret_s8_m64(a),
1863*35ffd701SAndroid Build Coastguard Worker vreinterpret_s8_u64(vget_low_u64(vreinterpretq_u64_m128(b))));
1864*35ffd701SAndroid Build Coastguard Worker vst1_s8((int8_t *) mem_addr, masked);
1865*35ffd701SAndroid Build Coastguard Worker }
1866*35ffd701SAndroid Build Coastguard Worker
1867*35ffd701SAndroid Build Coastguard Worker // Conditionally store 8-bit integer elements from a into memory using mask
1868*35ffd701SAndroid Build Coastguard Worker // (elements are not stored when the highest bit is not set in the corresponding
1869*35ffd701SAndroid Build Coastguard Worker // element) and a non-temporal memory hint.
1870*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_maskmovq
1871*35ffd701SAndroid Build Coastguard Worker #define _m_maskmovq(a, mask, mem_addr) _mm_maskmove_si64(a, mask, mem_addr)
1872*35ffd701SAndroid Build Coastguard Worker
1873*35ffd701SAndroid Build Coastguard Worker // Compare packed signed 16-bit integers in a and b, and store packed maximum
1874*35ffd701SAndroid Build Coastguard Worker // values in dst.
1875*35ffd701SAndroid Build Coastguard Worker //
1876*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
1877*35ffd701SAndroid Build Coastguard Worker // i := j*16
1878*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := MAX(a[i+15:i], b[i+15:i])
1879*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1880*35ffd701SAndroid Build Coastguard Worker //
1881*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16
_mm_max_pi16(__m64 a,__m64 b)1882*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_max_pi16(__m64 a, __m64 b)
1883*35ffd701SAndroid Build Coastguard Worker {
1884*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s16(
1885*35ffd701SAndroid Build Coastguard Worker vmax_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b)));
1886*35ffd701SAndroid Build Coastguard Worker }
1887*35ffd701SAndroid Build Coastguard Worker
1888*35ffd701SAndroid Build Coastguard Worker // Computes the maximums of the four single-precision, floating-point values of
1889*35ffd701SAndroid Build Coastguard Worker // a and b.
1890*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/ff5d607a(v=vs.100).aspx
_mm_max_ps(__m128 a,__m128 b)1891*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_max_ps(__m128 a, __m128 b)
1892*35ffd701SAndroid Build Coastguard Worker {
1893*35ffd701SAndroid Build Coastguard Worker #if SSE2NEON_PRECISE_MINMAX
1894*35ffd701SAndroid Build Coastguard Worker float32x4_t _a = vreinterpretq_f32_m128(a);
1895*35ffd701SAndroid Build Coastguard Worker float32x4_t _b = vreinterpretq_f32_m128(b);
1896*35ffd701SAndroid Build Coastguard Worker return vbslq_f32(vcltq_f32(_b, _a), _a, _b);
1897*35ffd701SAndroid Build Coastguard Worker #else
1898*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1899*35ffd701SAndroid Build Coastguard Worker vmaxq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
1900*35ffd701SAndroid Build Coastguard Worker #endif
1901*35ffd701SAndroid Build Coastguard Worker }
1902*35ffd701SAndroid Build Coastguard Worker
1903*35ffd701SAndroid Build Coastguard Worker // Compare packed unsigned 8-bit integers in a and b, and store packed maximum
1904*35ffd701SAndroid Build Coastguard Worker // values in dst.
1905*35ffd701SAndroid Build Coastguard Worker //
1906*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
1907*35ffd701SAndroid Build Coastguard Worker // i := j*8
1908*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := MAX(a[i+7:i], b[i+7:i])
1909*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1910*35ffd701SAndroid Build Coastguard Worker //
1911*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8
_mm_max_pu8(__m64 a,__m64 b)1912*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_max_pu8(__m64 a, __m64 b)
1913*35ffd701SAndroid Build Coastguard Worker {
1914*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_u8(
1915*35ffd701SAndroid Build Coastguard Worker vmax_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b)));
1916*35ffd701SAndroid Build Coastguard Worker }
1917*35ffd701SAndroid Build Coastguard Worker
1918*35ffd701SAndroid Build Coastguard Worker // Computes the maximum of the two lower scalar single-precision floating point
1919*35ffd701SAndroid Build Coastguard Worker // values of a and b.
1920*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/s6db5esz(v=vs.100).aspx
_mm_max_ss(__m128 a,__m128 b)1921*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_max_ss(__m128 a, __m128 b)
1922*35ffd701SAndroid Build Coastguard Worker {
1923*35ffd701SAndroid Build Coastguard Worker float32_t value = vgetq_lane_f32(_mm_max_ps(a, b), 0);
1924*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1925*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0));
1926*35ffd701SAndroid Build Coastguard Worker }
1927*35ffd701SAndroid Build Coastguard Worker
1928*35ffd701SAndroid Build Coastguard Worker // Compare packed signed 16-bit integers in a and b, and store packed minimum
1929*35ffd701SAndroid Build Coastguard Worker // values in dst.
1930*35ffd701SAndroid Build Coastguard Worker //
1931*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
1932*35ffd701SAndroid Build Coastguard Worker // i := j*16
1933*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := MIN(a[i+15:i], b[i+15:i])
1934*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1935*35ffd701SAndroid Build Coastguard Worker //
1936*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16
_mm_min_pi16(__m64 a,__m64 b)1937*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_min_pi16(__m64 a, __m64 b)
1938*35ffd701SAndroid Build Coastguard Worker {
1939*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s16(
1940*35ffd701SAndroid Build Coastguard Worker vmin_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b)));
1941*35ffd701SAndroid Build Coastguard Worker }
1942*35ffd701SAndroid Build Coastguard Worker
1943*35ffd701SAndroid Build Coastguard Worker // Computes the minima of the four single-precision, floating-point values of a
1944*35ffd701SAndroid Build Coastguard Worker // and b.
1945*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/wh13kadz(v=vs.100).aspx
_mm_min_ps(__m128 a,__m128 b)1946*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_min_ps(__m128 a, __m128 b)
1947*35ffd701SAndroid Build Coastguard Worker {
1948*35ffd701SAndroid Build Coastguard Worker #if SSE2NEON_PRECISE_MINMAX
1949*35ffd701SAndroid Build Coastguard Worker float32x4_t _a = vreinterpretq_f32_m128(a);
1950*35ffd701SAndroid Build Coastguard Worker float32x4_t _b = vreinterpretq_f32_m128(b);
1951*35ffd701SAndroid Build Coastguard Worker return vbslq_f32(vcltq_f32(_a, _b), _a, _b);
1952*35ffd701SAndroid Build Coastguard Worker #else
1953*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1954*35ffd701SAndroid Build Coastguard Worker vminq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
1955*35ffd701SAndroid Build Coastguard Worker #endif
1956*35ffd701SAndroid Build Coastguard Worker }
1957*35ffd701SAndroid Build Coastguard Worker
1958*35ffd701SAndroid Build Coastguard Worker // Compare packed unsigned 8-bit integers in a and b, and store packed minimum
1959*35ffd701SAndroid Build Coastguard Worker // values in dst.
1960*35ffd701SAndroid Build Coastguard Worker //
1961*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
1962*35ffd701SAndroid Build Coastguard Worker // i := j*8
1963*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := MIN(a[i+7:i], b[i+7:i])
1964*35ffd701SAndroid Build Coastguard Worker // ENDFOR
1965*35ffd701SAndroid Build Coastguard Worker //
1966*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8
_mm_min_pu8(__m64 a,__m64 b)1967*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_min_pu8(__m64 a, __m64 b)
1968*35ffd701SAndroid Build Coastguard Worker {
1969*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_u8(
1970*35ffd701SAndroid Build Coastguard Worker vmin_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b)));
1971*35ffd701SAndroid Build Coastguard Worker }
1972*35ffd701SAndroid Build Coastguard Worker
1973*35ffd701SAndroid Build Coastguard Worker // Computes the minimum of the two lower scalar single-precision floating point
1974*35ffd701SAndroid Build Coastguard Worker // values of a and b.
1975*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/0a9y7xaa(v=vs.100).aspx
_mm_min_ss(__m128 a,__m128 b)1976*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_min_ss(__m128 a, __m128 b)
1977*35ffd701SAndroid Build Coastguard Worker {
1978*35ffd701SAndroid Build Coastguard Worker float32_t value = vgetq_lane_f32(_mm_min_ps(a, b), 0);
1979*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1980*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0));
1981*35ffd701SAndroid Build Coastguard Worker }
1982*35ffd701SAndroid Build Coastguard Worker
1983*35ffd701SAndroid Build Coastguard Worker // Sets the low word to the single-precision, floating-point value of b
1984*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/35hdzazd(v=vs.100)
_mm_move_ss(__m128 a,__m128 b)1985*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_move_ss(__m128 a, __m128 b)
1986*35ffd701SAndroid Build Coastguard Worker {
1987*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
1988*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f32(vgetq_lane_f32(vreinterpretq_f32_m128(b), 0),
1989*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a), 0));
1990*35ffd701SAndroid Build Coastguard Worker }
1991*35ffd701SAndroid Build Coastguard Worker
1992*35ffd701SAndroid Build Coastguard Worker // Moves the upper two values of B into the lower two values of A.
1993*35ffd701SAndroid Build Coastguard Worker //
1994*35ffd701SAndroid Build Coastguard Worker // r3 := a3
1995*35ffd701SAndroid Build Coastguard Worker // r2 := a2
1996*35ffd701SAndroid Build Coastguard Worker // r1 := b3
1997*35ffd701SAndroid Build Coastguard Worker // r0 := b2
_mm_movehl_ps(__m128 __A,__m128 __B)1998*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_movehl_ps(__m128 __A, __m128 __B)
1999*35ffd701SAndroid Build Coastguard Worker {
2000*35ffd701SAndroid Build Coastguard Worker float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(__A));
2001*35ffd701SAndroid Build Coastguard Worker float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(__B));
2002*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(b32, a32));
2003*35ffd701SAndroid Build Coastguard Worker }
2004*35ffd701SAndroid Build Coastguard Worker
2005*35ffd701SAndroid Build Coastguard Worker // Moves the lower two values of B into the upper two values of A.
2006*35ffd701SAndroid Build Coastguard Worker //
2007*35ffd701SAndroid Build Coastguard Worker // r3 := b1
2008*35ffd701SAndroid Build Coastguard Worker // r2 := b0
2009*35ffd701SAndroid Build Coastguard Worker // r1 := a1
2010*35ffd701SAndroid Build Coastguard Worker // r0 := a0
_mm_movelh_ps(__m128 __A,__m128 __B)2011*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_movelh_ps(__m128 __A, __m128 __B)
2012*35ffd701SAndroid Build Coastguard Worker {
2013*35ffd701SAndroid Build Coastguard Worker float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(__A));
2014*35ffd701SAndroid Build Coastguard Worker float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(__B));
2015*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(a10, b10));
2016*35ffd701SAndroid Build Coastguard Worker }
2017*35ffd701SAndroid Build Coastguard Worker
2018*35ffd701SAndroid Build Coastguard Worker // Create mask from the most significant bit of each 8-bit element in a, and
2019*35ffd701SAndroid Build Coastguard Worker // store the result in dst.
2020*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movemask_pi8
_mm_movemask_pi8(__m64 a)2021*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_movemask_pi8(__m64 a)
2022*35ffd701SAndroid Build Coastguard Worker {
2023*35ffd701SAndroid Build Coastguard Worker uint8x8_t input = vreinterpret_u8_m64(a);
2024*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
2025*35ffd701SAndroid Build Coastguard Worker static const int8x8_t shift = {0, 1, 2, 3, 4, 5, 6, 7};
2026*35ffd701SAndroid Build Coastguard Worker uint8x8_t tmp = vshr_n_u8(input, 7);
2027*35ffd701SAndroid Build Coastguard Worker return vaddv_u8(vshl_u8(tmp, shift));
2028*35ffd701SAndroid Build Coastguard Worker #else
2029*35ffd701SAndroid Build Coastguard Worker // Refer the implementation of `_mm_movemask_epi8`
2030*35ffd701SAndroid Build Coastguard Worker uint16x4_t high_bits = vreinterpret_u16_u8(vshr_n_u8(input, 7));
2031*35ffd701SAndroid Build Coastguard Worker uint32x2_t paired16 =
2032*35ffd701SAndroid Build Coastguard Worker vreinterpret_u32_u16(vsra_n_u16(high_bits, high_bits, 7));
2033*35ffd701SAndroid Build Coastguard Worker uint8x8_t paired32 =
2034*35ffd701SAndroid Build Coastguard Worker vreinterpret_u8_u32(vsra_n_u32(paired16, paired16, 14));
2035*35ffd701SAndroid Build Coastguard Worker return vget_lane_u8(paired32, 0) | ((int) vget_lane_u8(paired32, 4) << 4);
2036*35ffd701SAndroid Build Coastguard Worker #endif
2037*35ffd701SAndroid Build Coastguard Worker }
2038*35ffd701SAndroid Build Coastguard Worker
2039*35ffd701SAndroid Build Coastguard Worker // NEON does not provide this method
2040*35ffd701SAndroid Build Coastguard Worker // Creates a 4-bit mask from the most significant bits of the four
2041*35ffd701SAndroid Build Coastguard Worker // single-precision, floating-point values.
2042*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/4490ys29(v=vs.100).aspx
_mm_movemask_ps(__m128 a)2043*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_movemask_ps(__m128 a)
2044*35ffd701SAndroid Build Coastguard Worker {
2045*35ffd701SAndroid Build Coastguard Worker uint32x4_t input = vreinterpretq_u32_m128(a);
2046*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
2047*35ffd701SAndroid Build Coastguard Worker static const int32x4_t shift = {0, 1, 2, 3};
2048*35ffd701SAndroid Build Coastguard Worker uint32x4_t tmp = vshrq_n_u32(input, 31);
2049*35ffd701SAndroid Build Coastguard Worker return vaddvq_u32(vshlq_u32(tmp, shift));
2050*35ffd701SAndroid Build Coastguard Worker #else
2051*35ffd701SAndroid Build Coastguard Worker // Uses the exact same method as _mm_movemask_epi8, see that for details.
2052*35ffd701SAndroid Build Coastguard Worker // Shift out everything but the sign bits with a 32-bit unsigned shift
2053*35ffd701SAndroid Build Coastguard Worker // right.
2054*35ffd701SAndroid Build Coastguard Worker uint64x2_t high_bits = vreinterpretq_u64_u32(vshrq_n_u32(input, 31));
2055*35ffd701SAndroid Build Coastguard Worker // Merge the two pairs together with a 64-bit unsigned shift right + add.
2056*35ffd701SAndroid Build Coastguard Worker uint8x16_t paired =
2057*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_u64(vsraq_n_u64(high_bits, high_bits, 31));
2058*35ffd701SAndroid Build Coastguard Worker // Extract the result.
2059*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u8(paired, 0) | (vgetq_lane_u8(paired, 8) << 2);
2060*35ffd701SAndroid Build Coastguard Worker #endif
2061*35ffd701SAndroid Build Coastguard Worker }
2062*35ffd701SAndroid Build Coastguard Worker
2063*35ffd701SAndroid Build Coastguard Worker // Multiplies the four single-precision, floating-point values of a and b.
2064*35ffd701SAndroid Build Coastguard Worker //
2065*35ffd701SAndroid Build Coastguard Worker // r0 := a0 * b0
2066*35ffd701SAndroid Build Coastguard Worker // r1 := a1 * b1
2067*35ffd701SAndroid Build Coastguard Worker // r2 := a2 * b2
2068*35ffd701SAndroid Build Coastguard Worker // r3 := a3 * b3
2069*35ffd701SAndroid Build Coastguard Worker //
2070*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/22kbk6t9(v=vs.100).aspx
_mm_mul_ps(__m128 a,__m128 b)2071*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b)
2072*35ffd701SAndroid Build Coastguard Worker {
2073*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
2074*35ffd701SAndroid Build Coastguard Worker vmulq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
2075*35ffd701SAndroid Build Coastguard Worker }
2076*35ffd701SAndroid Build Coastguard Worker
2077*35ffd701SAndroid Build Coastguard Worker // Multiply the lower single-precision (32-bit) floating-point element in a and
2078*35ffd701SAndroid Build Coastguard Worker // b, store the result in the lower element of dst, and copy the upper 3 packed
2079*35ffd701SAndroid Build Coastguard Worker // elements from a to the upper elements of dst.
2080*35ffd701SAndroid Build Coastguard Worker //
2081*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := a[31:0] * b[31:0]
2082*35ffd701SAndroid Build Coastguard Worker // dst[127:32] := a[127:32]
2083*35ffd701SAndroid Build Coastguard Worker //
2084*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_ss
_mm_mul_ss(__m128 a,__m128 b)2085*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_mul_ss(__m128 a, __m128 b)
2086*35ffd701SAndroid Build Coastguard Worker {
2087*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_mul_ps(a, b));
2088*35ffd701SAndroid Build Coastguard Worker }
2089*35ffd701SAndroid Build Coastguard Worker
2090*35ffd701SAndroid Build Coastguard Worker // Multiply the packed unsigned 16-bit integers in a and b, producing
2091*35ffd701SAndroid Build Coastguard Worker // intermediate 32-bit integers, and store the high 16 bits of the intermediate
2092*35ffd701SAndroid Build Coastguard Worker // integers in dst.
2093*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_pu16
_mm_mulhi_pu16(__m64 a,__m64 b)2094*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_mulhi_pu16(__m64 a, __m64 b)
2095*35ffd701SAndroid Build Coastguard Worker {
2096*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_u16(vshrn_n_u32(
2097*35ffd701SAndroid Build Coastguard Worker vmull_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b)), 16));
2098*35ffd701SAndroid Build Coastguard Worker }
2099*35ffd701SAndroid Build Coastguard Worker
2100*35ffd701SAndroid Build Coastguard Worker // Computes the bitwise OR of the four single-precision, floating-point values
2101*35ffd701SAndroid Build Coastguard Worker // of a and b.
2102*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/7ctdsyy0(v=vs.100).aspx
_mm_or_ps(__m128 a,__m128 b)2103*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b)
2104*35ffd701SAndroid Build Coastguard Worker {
2105*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_s32(
2106*35ffd701SAndroid Build Coastguard Worker vorrq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b)));
2107*35ffd701SAndroid Build Coastguard Worker }
2108*35ffd701SAndroid Build Coastguard Worker
2109*35ffd701SAndroid Build Coastguard Worker // Average packed unsigned 8-bit integers in a and b, and store the results in
2110*35ffd701SAndroid Build Coastguard Worker // dst.
2111*35ffd701SAndroid Build Coastguard Worker //
2112*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
2113*35ffd701SAndroid Build Coastguard Worker // i := j*8
2114*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1
2115*35ffd701SAndroid Build Coastguard Worker // ENDFOR
2116*35ffd701SAndroid Build Coastguard Worker //
2117*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgb
2118*35ffd701SAndroid Build Coastguard Worker #define _m_pavgb(a, b) _mm_avg_pu8(a, b)
2119*35ffd701SAndroid Build Coastguard Worker
2120*35ffd701SAndroid Build Coastguard Worker // Average packed unsigned 16-bit integers in a and b, and store the results in
2121*35ffd701SAndroid Build Coastguard Worker // dst.
2122*35ffd701SAndroid Build Coastguard Worker //
2123*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
2124*35ffd701SAndroid Build Coastguard Worker // i := j*16
2125*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1
2126*35ffd701SAndroid Build Coastguard Worker // ENDFOR
2127*35ffd701SAndroid Build Coastguard Worker //
2128*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgw
2129*35ffd701SAndroid Build Coastguard Worker #define _m_pavgw(a, b) _mm_avg_pu16(a, b)
2130*35ffd701SAndroid Build Coastguard Worker
2131*35ffd701SAndroid Build Coastguard Worker // Extract a 16-bit integer from a, selected with imm8, and store the result in
2132*35ffd701SAndroid Build Coastguard Worker // the lower element of dst.
2133*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pextrw
2134*35ffd701SAndroid Build Coastguard Worker #define _m_pextrw(a, imm) _mm_extract_pi16(a, imm)
2135*35ffd701SAndroid Build Coastguard Worker
2136*35ffd701SAndroid Build Coastguard Worker // Copy a to dst, and insert the 16-bit integer i into dst at the location
2137*35ffd701SAndroid Build Coastguard Worker // specified by imm8.
2138*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_pinsrw
2139*35ffd701SAndroid Build Coastguard Worker #define _m_pinsrw(a, i, imm) _mm_insert_pi16(a, i, imm)
2140*35ffd701SAndroid Build Coastguard Worker
2141*35ffd701SAndroid Build Coastguard Worker // Compare packed signed 16-bit integers in a and b, and store packed maximum
2142*35ffd701SAndroid Build Coastguard Worker // values in dst.
2143*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxsw
2144*35ffd701SAndroid Build Coastguard Worker #define _m_pmaxsw(a, b) _mm_max_pi16(a, b)
2145*35ffd701SAndroid Build Coastguard Worker
2146*35ffd701SAndroid Build Coastguard Worker // Compare packed unsigned 8-bit integers in a and b, and store packed maximum
2147*35ffd701SAndroid Build Coastguard Worker // values in dst.
2148*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxub
2149*35ffd701SAndroid Build Coastguard Worker #define _m_pmaxub(a, b) _mm_max_pu8(a, b)
2150*35ffd701SAndroid Build Coastguard Worker
2151*35ffd701SAndroid Build Coastguard Worker // Compare packed signed 16-bit integers in a and b, and store packed minimum
2152*35ffd701SAndroid Build Coastguard Worker // values in dst.
2153*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminsw
2154*35ffd701SAndroid Build Coastguard Worker #define _m_pminsw(a, b) _mm_min_pi16(a, b)
2155*35ffd701SAndroid Build Coastguard Worker
2156*35ffd701SAndroid Build Coastguard Worker // Compare packed unsigned 8-bit integers in a and b, and store packed minimum
2157*35ffd701SAndroid Build Coastguard Worker // values in dst.
2158*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminub
2159*35ffd701SAndroid Build Coastguard Worker #define _m_pminub(a, b) _mm_min_pu8(a, b)
2160*35ffd701SAndroid Build Coastguard Worker
2161*35ffd701SAndroid Build Coastguard Worker // Create mask from the most significant bit of each 8-bit element in a, and
2162*35ffd701SAndroid Build Coastguard Worker // store the result in dst.
2163*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmovmskb
2164*35ffd701SAndroid Build Coastguard Worker #define _m_pmovmskb(a) _mm_movemask_pi8(a)
2165*35ffd701SAndroid Build Coastguard Worker
2166*35ffd701SAndroid Build Coastguard Worker // Multiply the packed unsigned 16-bit integers in a and b, producing
2167*35ffd701SAndroid Build Coastguard Worker // intermediate 32-bit integers, and store the high 16 bits of the intermediate
2168*35ffd701SAndroid Build Coastguard Worker // integers in dst.
2169*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmulhuw
2170*35ffd701SAndroid Build Coastguard Worker #define _m_pmulhuw(a, b) _mm_mulhi_pu16(a, b)
2171*35ffd701SAndroid Build Coastguard Worker
2172*35ffd701SAndroid Build Coastguard Worker // Loads one cache line of data from address p to a location closer to the
2173*35ffd701SAndroid Build Coastguard Worker // processor. https://msdn.microsoft.com/en-us/library/84szxsww(v=vs.100).aspx
_mm_prefetch(const void * p,int i)2174*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_prefetch(const void *p, int i)
2175*35ffd701SAndroid Build Coastguard Worker {
2176*35ffd701SAndroid Build Coastguard Worker (void) i;
2177*35ffd701SAndroid Build Coastguard Worker __builtin_prefetch(p);
2178*35ffd701SAndroid Build Coastguard Worker }
2179*35ffd701SAndroid Build Coastguard Worker
2180*35ffd701SAndroid Build Coastguard Worker // Compute the absolute differences of packed unsigned 8-bit integers in a and
2181*35ffd701SAndroid Build Coastguard Worker // b, then horizontally sum each consecutive 8 differences to produce four
2182*35ffd701SAndroid Build Coastguard Worker // unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low
2183*35ffd701SAndroid Build Coastguard Worker // 16 bits of dst.
2184*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_psadbw
2185*35ffd701SAndroid Build Coastguard Worker #define _m_psadbw(a, b) _mm_sad_pu8(a, b)
2186*35ffd701SAndroid Build Coastguard Worker
2187*35ffd701SAndroid Build Coastguard Worker // Shuffle 16-bit integers in a using the control in imm8, and store the results
2188*35ffd701SAndroid Build Coastguard Worker // in dst.
2189*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pshufw
2190*35ffd701SAndroid Build Coastguard Worker #define _m_pshufw(a, imm) _mm_shuffle_pi16(a, imm)
2191*35ffd701SAndroid Build Coastguard Worker
2192*35ffd701SAndroid Build Coastguard Worker // Compute the approximate reciprocal of packed single-precision (32-bit)
2193*35ffd701SAndroid Build Coastguard Worker // floating-point elements in a, and store the results in dst. The maximum
2194*35ffd701SAndroid Build Coastguard Worker // relative error for this approximation is less than 1.5*2^-12.
2195*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ps
_mm_rcp_ps(__m128 in)2196*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_rcp_ps(__m128 in)
2197*35ffd701SAndroid Build Coastguard Worker {
2198*35ffd701SAndroid Build Coastguard Worker float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in));
2199*35ffd701SAndroid Build Coastguard Worker recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in)));
2200*35ffd701SAndroid Build Coastguard Worker #if SSE2NEON_PRECISE_DIV
2201*35ffd701SAndroid Build Coastguard Worker // Additional Netwon-Raphson iteration for accuracy
2202*35ffd701SAndroid Build Coastguard Worker recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in)));
2203*35ffd701SAndroid Build Coastguard Worker #endif
2204*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(recip);
2205*35ffd701SAndroid Build Coastguard Worker }
2206*35ffd701SAndroid Build Coastguard Worker
2207*35ffd701SAndroid Build Coastguard Worker // Compute the approximate reciprocal of the lower single-precision (32-bit)
2208*35ffd701SAndroid Build Coastguard Worker // floating-point element in a, store the result in the lower element of dst,
2209*35ffd701SAndroid Build Coastguard Worker // and copy the upper 3 packed elements from a to the upper elements of dst. The
2210*35ffd701SAndroid Build Coastguard Worker // maximum relative error for this approximation is less than 1.5*2^-12.
2211*35ffd701SAndroid Build Coastguard Worker //
2212*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := (1.0 / a[31:0])
2213*35ffd701SAndroid Build Coastguard Worker // dst[127:32] := a[127:32]
2214*35ffd701SAndroid Build Coastguard Worker //
2215*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ss
_mm_rcp_ss(__m128 a)2216*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_rcp_ss(__m128 a)
2217*35ffd701SAndroid Build Coastguard Worker {
2218*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_rcp_ps(a));
2219*35ffd701SAndroid Build Coastguard Worker }
2220*35ffd701SAndroid Build Coastguard Worker
2221*35ffd701SAndroid Build Coastguard Worker // Computes the approximations of the reciprocal square roots of the four
2222*35ffd701SAndroid Build Coastguard Worker // single-precision floating point values of in.
2223*35ffd701SAndroid Build Coastguard Worker // The current precision is 1% error.
2224*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx
_mm_rsqrt_ps(__m128 in)2225*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in)
2226*35ffd701SAndroid Build Coastguard Worker {
2227*35ffd701SAndroid Build Coastguard Worker float32x4_t out = vrsqrteq_f32(vreinterpretq_f32_m128(in));
2228*35ffd701SAndroid Build Coastguard Worker #if SSE2NEON_PRECISE_SQRT
2229*35ffd701SAndroid Build Coastguard Worker // Additional Netwon-Raphson iteration for accuracy
2230*35ffd701SAndroid Build Coastguard Worker out = vmulq_f32(
2231*35ffd701SAndroid Build Coastguard Worker out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out));
2232*35ffd701SAndroid Build Coastguard Worker out = vmulq_f32(
2233*35ffd701SAndroid Build Coastguard Worker out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out));
2234*35ffd701SAndroid Build Coastguard Worker #endif
2235*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(out);
2236*35ffd701SAndroid Build Coastguard Worker }
2237*35ffd701SAndroid Build Coastguard Worker
2238*35ffd701SAndroid Build Coastguard Worker // Compute the approximate reciprocal square root of the lower single-precision
2239*35ffd701SAndroid Build Coastguard Worker // (32-bit) floating-point element in a, store the result in the lower element
2240*35ffd701SAndroid Build Coastguard Worker // of dst, and copy the upper 3 packed elements from a to the upper elements of
2241*35ffd701SAndroid Build Coastguard Worker // dst.
2242*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rsqrt_ss
_mm_rsqrt_ss(__m128 in)2243*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_rsqrt_ss(__m128 in)
2244*35ffd701SAndroid Build Coastguard Worker {
2245*35ffd701SAndroid Build Coastguard Worker return vsetq_lane_f32(vgetq_lane_f32(_mm_rsqrt_ps(in), 0), in, 0);
2246*35ffd701SAndroid Build Coastguard Worker }
2247*35ffd701SAndroid Build Coastguard Worker
2248*35ffd701SAndroid Build Coastguard Worker // Compute the absolute differences of packed unsigned 8-bit integers in a and
2249*35ffd701SAndroid Build Coastguard Worker // b, then horizontally sum each consecutive 8 differences to produce four
2250*35ffd701SAndroid Build Coastguard Worker // unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low
2251*35ffd701SAndroid Build Coastguard Worker // 16 bits of dst.
2252*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_pu8
_mm_sad_pu8(__m64 a,__m64 b)2253*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_sad_pu8(__m64 a, __m64 b)
2254*35ffd701SAndroid Build Coastguard Worker {
2255*35ffd701SAndroid Build Coastguard Worker uint64x1_t t = vpaddl_u32(vpaddl_u16(
2256*35ffd701SAndroid Build Coastguard Worker vpaddl_u8(vabd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b)))));
2257*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_u16(
2258*35ffd701SAndroid Build Coastguard Worker vset_lane_u16(vget_lane_u64(t, 0), vdup_n_u16(0), 0));
2259*35ffd701SAndroid Build Coastguard Worker }
2260*35ffd701SAndroid Build Coastguard Worker
2261*35ffd701SAndroid Build Coastguard Worker // Sets the four single-precision, floating-point values to the four inputs.
2262*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/afh0zf75(v=vs.100).aspx
_mm_set_ps(float w,float z,float y,float x)2263*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_set_ps(float w, float z, float y, float x)
2264*35ffd701SAndroid Build Coastguard Worker {
2265*35ffd701SAndroid Build Coastguard Worker float ALIGN_STRUCT(16) data[4] = {x, y, z, w};
2266*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vld1q_f32(data));
2267*35ffd701SAndroid Build Coastguard Worker }
2268*35ffd701SAndroid Build Coastguard Worker
2269*35ffd701SAndroid Build Coastguard Worker // Sets the four single-precision, floating-point values to w.
2270*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx
_mm_set_ps1(float _w)2271*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_set_ps1(float _w)
2272*35ffd701SAndroid Build Coastguard Worker {
2273*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vdupq_n_f32(_w));
2274*35ffd701SAndroid Build Coastguard Worker }
2275*35ffd701SAndroid Build Coastguard Worker
2276*35ffd701SAndroid Build Coastguard Worker // Macro: Set the rounding mode bits of the MXCSR control and status register to
2277*35ffd701SAndroid Build Coastguard Worker // the value in unsigned 32-bit integer a. The rounding mode may contain any of
2278*35ffd701SAndroid Build Coastguard Worker // the following flags: _MM_ROUND_NEAREST, _MM_ROUND_DOWN, _MM_ROUND_UP,
2279*35ffd701SAndroid Build Coastguard Worker // _MM_ROUND_TOWARD_ZERO
2280*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_SET_ROUNDING_MODE
_MM_SET_ROUNDING_MODE(int rounding)2281*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _MM_SET_ROUNDING_MODE(int rounding)
2282*35ffd701SAndroid Build Coastguard Worker {
2283*35ffd701SAndroid Build Coastguard Worker union {
2284*35ffd701SAndroid Build Coastguard Worker fpcr_bitfield field;
2285*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
2286*35ffd701SAndroid Build Coastguard Worker uint64_t value;
2287*35ffd701SAndroid Build Coastguard Worker #else
2288*35ffd701SAndroid Build Coastguard Worker uint32_t value;
2289*35ffd701SAndroid Build Coastguard Worker #endif
2290*35ffd701SAndroid Build Coastguard Worker } r;
2291*35ffd701SAndroid Build Coastguard Worker
2292*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
2293*35ffd701SAndroid Build Coastguard Worker asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */
2294*35ffd701SAndroid Build Coastguard Worker #else
2295*35ffd701SAndroid Build Coastguard Worker asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */
2296*35ffd701SAndroid Build Coastguard Worker #endif
2297*35ffd701SAndroid Build Coastguard Worker
2298*35ffd701SAndroid Build Coastguard Worker switch (rounding) {
2299*35ffd701SAndroid Build Coastguard Worker case _MM_ROUND_TOWARD_ZERO:
2300*35ffd701SAndroid Build Coastguard Worker r.field.bit22 = 1;
2301*35ffd701SAndroid Build Coastguard Worker r.field.bit23 = 1;
2302*35ffd701SAndroid Build Coastguard Worker break;
2303*35ffd701SAndroid Build Coastguard Worker case _MM_ROUND_DOWN:
2304*35ffd701SAndroid Build Coastguard Worker r.field.bit22 = 0;
2305*35ffd701SAndroid Build Coastguard Worker r.field.bit23 = 1;
2306*35ffd701SAndroid Build Coastguard Worker break;
2307*35ffd701SAndroid Build Coastguard Worker case _MM_ROUND_UP:
2308*35ffd701SAndroid Build Coastguard Worker r.field.bit22 = 1;
2309*35ffd701SAndroid Build Coastguard Worker r.field.bit23 = 0;
2310*35ffd701SAndroid Build Coastguard Worker break;
2311*35ffd701SAndroid Build Coastguard Worker default: //_MM_ROUND_NEAREST
2312*35ffd701SAndroid Build Coastguard Worker r.field.bit22 = 0;
2313*35ffd701SAndroid Build Coastguard Worker r.field.bit23 = 0;
2314*35ffd701SAndroid Build Coastguard Worker }
2315*35ffd701SAndroid Build Coastguard Worker
2316*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
2317*35ffd701SAndroid Build Coastguard Worker asm volatile("msr FPCR, %0" ::"r"(r)); /* write */
2318*35ffd701SAndroid Build Coastguard Worker #else
2319*35ffd701SAndroid Build Coastguard Worker asm volatile("vmsr FPSCR, %0" ::"r"(r)); /* write */
2320*35ffd701SAndroid Build Coastguard Worker #endif
2321*35ffd701SAndroid Build Coastguard Worker }
2322*35ffd701SAndroid Build Coastguard Worker
2323*35ffd701SAndroid Build Coastguard Worker // Copy single-precision (32-bit) floating-point element a to the lower element
2324*35ffd701SAndroid Build Coastguard Worker // of dst, and zero the upper 3 elements.
2325*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_ss
_mm_set_ss(float a)2326*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_set_ss(float a)
2327*35ffd701SAndroid Build Coastguard Worker {
2328*35ffd701SAndroid Build Coastguard Worker float ALIGN_STRUCT(16) data[4] = {a, 0, 0, 0};
2329*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vld1q_f32(data));
2330*35ffd701SAndroid Build Coastguard Worker }
2331*35ffd701SAndroid Build Coastguard Worker
2332*35ffd701SAndroid Build Coastguard Worker // Sets the four single-precision, floating-point values to w.
2333*35ffd701SAndroid Build Coastguard Worker //
2334*35ffd701SAndroid Build Coastguard Worker // r0 := r1 := r2 := r3 := w
2335*35ffd701SAndroid Build Coastguard Worker //
2336*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx
_mm_set1_ps(float _w)2337*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_set1_ps(float _w)
2338*35ffd701SAndroid Build Coastguard Worker {
2339*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vdupq_n_f32(_w));
2340*35ffd701SAndroid Build Coastguard Worker }
2341*35ffd701SAndroid Build Coastguard Worker
_mm_setcsr(unsigned int a)2342*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_setcsr(unsigned int a)
2343*35ffd701SAndroid Build Coastguard Worker {
2344*35ffd701SAndroid Build Coastguard Worker _MM_SET_ROUNDING_MODE(a);
2345*35ffd701SAndroid Build Coastguard Worker }
2346*35ffd701SAndroid Build Coastguard Worker
2347*35ffd701SAndroid Build Coastguard Worker // Sets the four single-precision, floating-point values to the four inputs in
2348*35ffd701SAndroid Build Coastguard Worker // reverse order.
2349*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx
_mm_setr_ps(float w,float z,float y,float x)2350*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_setr_ps(float w, float z, float y, float x)
2351*35ffd701SAndroid Build Coastguard Worker {
2352*35ffd701SAndroid Build Coastguard Worker float ALIGN_STRUCT(16) data[4] = {w, z, y, x};
2353*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vld1q_f32(data));
2354*35ffd701SAndroid Build Coastguard Worker }
2355*35ffd701SAndroid Build Coastguard Worker
2356*35ffd701SAndroid Build Coastguard Worker // Clears the four single-precision, floating-point values.
2357*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/tk1t2tbz(v=vs.100).aspx
_mm_setzero_ps(void)2358*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_setzero_ps(void)
2359*35ffd701SAndroid Build Coastguard Worker {
2360*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vdupq_n_f32(0));
2361*35ffd701SAndroid Build Coastguard Worker }
2362*35ffd701SAndroid Build Coastguard Worker
2363*35ffd701SAndroid Build Coastguard Worker // Shuffle 16-bit integers in a using the control in imm8, and store the results
2364*35ffd701SAndroid Build Coastguard Worker // in dst.
2365*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pi16
2366*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_shufflevector)
2367*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_pi16(a, imm) \
2368*35ffd701SAndroid Build Coastguard Worker __extension__({ \
2369*35ffd701SAndroid Build Coastguard Worker vreinterpret_m64_s16(__builtin_shufflevector( \
2370*35ffd701SAndroid Build Coastguard Worker vreinterpret_s16_m64(a), vreinterpret_s16_m64(a), (imm & 0x3), \
2371*35ffd701SAndroid Build Coastguard Worker ((imm >> 2) & 0x3), ((imm >> 4) & 0x3), ((imm >> 6) & 0x3))); \
2372*35ffd701SAndroid Build Coastguard Worker })
2373*35ffd701SAndroid Build Coastguard Worker #else
2374*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_pi16(a, imm) \
2375*35ffd701SAndroid Build Coastguard Worker __extension__({ \
2376*35ffd701SAndroid Build Coastguard Worker int16x4_t ret; \
2377*35ffd701SAndroid Build Coastguard Worker ret = \
2378*35ffd701SAndroid Build Coastguard Worker vmov_n_s16(vget_lane_s16(vreinterpret_s16_m64(a), (imm) & (0x3))); \
2379*35ffd701SAndroid Build Coastguard Worker ret = vset_lane_s16( \
2380*35ffd701SAndroid Build Coastguard Worker vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 2) & 0x3), ret, \
2381*35ffd701SAndroid Build Coastguard Worker 1); \
2382*35ffd701SAndroid Build Coastguard Worker ret = vset_lane_s16( \
2383*35ffd701SAndroid Build Coastguard Worker vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 4) & 0x3), ret, \
2384*35ffd701SAndroid Build Coastguard Worker 2); \
2385*35ffd701SAndroid Build Coastguard Worker ret = vset_lane_s16( \
2386*35ffd701SAndroid Build Coastguard Worker vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 6) & 0x3), ret, \
2387*35ffd701SAndroid Build Coastguard Worker 3); \
2388*35ffd701SAndroid Build Coastguard Worker vreinterpret_m64_s16(ret); \
2389*35ffd701SAndroid Build Coastguard Worker })
2390*35ffd701SAndroid Build Coastguard Worker #endif
2391*35ffd701SAndroid Build Coastguard Worker
2392*35ffd701SAndroid Build Coastguard Worker // Guarantees that every preceding store is globally visible before any
2393*35ffd701SAndroid Build Coastguard Worker // subsequent store.
2394*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/5h2w73d1%28v=vs.90%29.aspx
_mm_sfence(void)2395*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_sfence(void)
2396*35ffd701SAndroid Build Coastguard Worker {
2397*35ffd701SAndroid Build Coastguard Worker __sync_synchronize();
2398*35ffd701SAndroid Build Coastguard Worker }
2399*35ffd701SAndroid Build Coastguard Worker
2400*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128 _mm_shuffle_ps(__m128 a, __m128 b, __constrange(0,255)
2401*35ffd701SAndroid Build Coastguard Worker // int imm)
2402*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_shufflevector)
2403*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_ps(a, b, imm) \
2404*35ffd701SAndroid Build Coastguard Worker __extension__({ \
2405*35ffd701SAndroid Build Coastguard Worker float32x4_t _input1 = vreinterpretq_f32_m128(a); \
2406*35ffd701SAndroid Build Coastguard Worker float32x4_t _input2 = vreinterpretq_f32_m128(b); \
2407*35ffd701SAndroid Build Coastguard Worker float32x4_t _shuf = __builtin_shufflevector( \
2408*35ffd701SAndroid Build Coastguard Worker _input1, _input2, (imm) & (0x3), ((imm) >> 2) & 0x3, \
2409*35ffd701SAndroid Build Coastguard Worker (((imm) >> 4) & 0x3) + 4, (((imm) >> 6) & 0x3) + 4); \
2410*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128_f32(_shuf); \
2411*35ffd701SAndroid Build Coastguard Worker })
2412*35ffd701SAndroid Build Coastguard Worker #else // generic
2413*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_ps(a, b, imm) \
2414*35ffd701SAndroid Build Coastguard Worker __extension__({ \
2415*35ffd701SAndroid Build Coastguard Worker __m128 ret; \
2416*35ffd701SAndroid Build Coastguard Worker switch (imm) { \
2417*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(1, 0, 3, 2): \
2418*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_1032((a), (b)); \
2419*35ffd701SAndroid Build Coastguard Worker break; \
2420*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 3, 0, 1): \
2421*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_2301((a), (b)); \
2422*35ffd701SAndroid Build Coastguard Worker break; \
2423*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(0, 3, 2, 1): \
2424*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_0321((a), (b)); \
2425*35ffd701SAndroid Build Coastguard Worker break; \
2426*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 1, 0, 3): \
2427*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_2103((a), (b)); \
2428*35ffd701SAndroid Build Coastguard Worker break; \
2429*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(1, 0, 1, 0): \
2430*35ffd701SAndroid Build Coastguard Worker ret = _mm_movelh_ps((a), (b)); \
2431*35ffd701SAndroid Build Coastguard Worker break; \
2432*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(1, 0, 0, 1): \
2433*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_1001((a), (b)); \
2434*35ffd701SAndroid Build Coastguard Worker break; \
2435*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(0, 1, 0, 1): \
2436*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_0101((a), (b)); \
2437*35ffd701SAndroid Build Coastguard Worker break; \
2438*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(3, 2, 1, 0): \
2439*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_3210((a), (b)); \
2440*35ffd701SAndroid Build Coastguard Worker break; \
2441*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(0, 0, 1, 1): \
2442*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_0011((a), (b)); \
2443*35ffd701SAndroid Build Coastguard Worker break; \
2444*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(0, 0, 2, 2): \
2445*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_0022((a), (b)); \
2446*35ffd701SAndroid Build Coastguard Worker break; \
2447*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 2, 0, 0): \
2448*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_2200((a), (b)); \
2449*35ffd701SAndroid Build Coastguard Worker break; \
2450*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(3, 2, 0, 2): \
2451*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_3202((a), (b)); \
2452*35ffd701SAndroid Build Coastguard Worker break; \
2453*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(3, 2, 3, 2): \
2454*35ffd701SAndroid Build Coastguard Worker ret = _mm_movehl_ps((b), (a)); \
2455*35ffd701SAndroid Build Coastguard Worker break; \
2456*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(1, 1, 3, 3): \
2457*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_1133((a), (b)); \
2458*35ffd701SAndroid Build Coastguard Worker break; \
2459*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 0, 1, 0): \
2460*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_2010((a), (b)); \
2461*35ffd701SAndroid Build Coastguard Worker break; \
2462*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 0, 0, 1): \
2463*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_2001((a), (b)); \
2464*35ffd701SAndroid Build Coastguard Worker break; \
2465*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 0, 3, 2): \
2466*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_2032((a), (b)); \
2467*35ffd701SAndroid Build Coastguard Worker break; \
2468*35ffd701SAndroid Build Coastguard Worker default: \
2469*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_ps_default((a), (b), (imm)); \
2470*35ffd701SAndroid Build Coastguard Worker break; \
2471*35ffd701SAndroid Build Coastguard Worker } \
2472*35ffd701SAndroid Build Coastguard Worker ret; \
2473*35ffd701SAndroid Build Coastguard Worker })
2474*35ffd701SAndroid Build Coastguard Worker #endif
2475*35ffd701SAndroid Build Coastguard Worker
2476*35ffd701SAndroid Build Coastguard Worker // Computes the approximations of square roots of the four single-precision,
2477*35ffd701SAndroid Build Coastguard Worker // floating-point values of a. First computes reciprocal square roots and then
2478*35ffd701SAndroid Build Coastguard Worker // reciprocals of the four values.
2479*35ffd701SAndroid Build Coastguard Worker //
2480*35ffd701SAndroid Build Coastguard Worker // r0 := sqrt(a0)
2481*35ffd701SAndroid Build Coastguard Worker // r1 := sqrt(a1)
2482*35ffd701SAndroid Build Coastguard Worker // r2 := sqrt(a2)
2483*35ffd701SAndroid Build Coastguard Worker // r3 := sqrt(a3)
2484*35ffd701SAndroid Build Coastguard Worker //
2485*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/8z67bwwk(v=vs.100).aspx
_mm_sqrt_ps(__m128 in)2486*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in)
2487*35ffd701SAndroid Build Coastguard Worker {
2488*35ffd701SAndroid Build Coastguard Worker #if SSE2NEON_PRECISE_SQRT
2489*35ffd701SAndroid Build Coastguard Worker float32x4_t recip = vrsqrteq_f32(vreinterpretq_f32_m128(in));
2490*35ffd701SAndroid Build Coastguard Worker
2491*35ffd701SAndroid Build Coastguard Worker // Test for vrsqrteq_f32(0) -> positive infinity case.
2492*35ffd701SAndroid Build Coastguard Worker // Change to zero, so that s * 1/sqrt(s) result is zero too.
2493*35ffd701SAndroid Build Coastguard Worker const uint32x4_t pos_inf = vdupq_n_u32(0x7F800000);
2494*35ffd701SAndroid Build Coastguard Worker const uint32x4_t div_by_zero =
2495*35ffd701SAndroid Build Coastguard Worker vceqq_u32(pos_inf, vreinterpretq_u32_f32(recip));
2496*35ffd701SAndroid Build Coastguard Worker recip = vreinterpretq_f32_u32(
2497*35ffd701SAndroid Build Coastguard Worker vandq_u32(vmvnq_u32(div_by_zero), vreinterpretq_u32_f32(recip)));
2498*35ffd701SAndroid Build Coastguard Worker
2499*35ffd701SAndroid Build Coastguard Worker // Additional Netwon-Raphson iteration for accuracy
2500*35ffd701SAndroid Build Coastguard Worker recip = vmulq_f32(
2501*35ffd701SAndroid Build Coastguard Worker vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)),
2502*35ffd701SAndroid Build Coastguard Worker recip);
2503*35ffd701SAndroid Build Coastguard Worker recip = vmulq_f32(
2504*35ffd701SAndroid Build Coastguard Worker vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)),
2505*35ffd701SAndroid Build Coastguard Worker recip);
2506*35ffd701SAndroid Build Coastguard Worker
2507*35ffd701SAndroid Build Coastguard Worker // sqrt(s) = s * 1/sqrt(s)
2508*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(in), recip));
2509*35ffd701SAndroid Build Coastguard Worker #elif defined(__aarch64__)
2510*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vsqrtq_f32(vreinterpretq_f32_m128(in)));
2511*35ffd701SAndroid Build Coastguard Worker #else
2512*35ffd701SAndroid Build Coastguard Worker float32x4_t recipsq = vrsqrteq_f32(vreinterpretq_f32_m128(in));
2513*35ffd701SAndroid Build Coastguard Worker float32x4_t sq = vrecpeq_f32(recipsq);
2514*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(sq);
2515*35ffd701SAndroid Build Coastguard Worker #endif
2516*35ffd701SAndroid Build Coastguard Worker }
2517*35ffd701SAndroid Build Coastguard Worker
2518*35ffd701SAndroid Build Coastguard Worker // Computes the approximation of the square root of the scalar single-precision
2519*35ffd701SAndroid Build Coastguard Worker // floating point value of in.
2520*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/ahfsc22d(v=vs.100).aspx
_mm_sqrt_ss(__m128 in)2521*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in)
2522*35ffd701SAndroid Build Coastguard Worker {
2523*35ffd701SAndroid Build Coastguard Worker float32_t value =
2524*35ffd701SAndroid Build Coastguard Worker vgetq_lane_f32(vreinterpretq_f32_m128(_mm_sqrt_ps(in)), 0);
2525*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
2526*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f32(value, vreinterpretq_f32_m128(in), 0));
2527*35ffd701SAndroid Build Coastguard Worker }
2528*35ffd701SAndroid Build Coastguard Worker
2529*35ffd701SAndroid Build Coastguard Worker // Stores four single-precision, floating-point values.
2530*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/s3h4ay6y(v=vs.100).aspx
_mm_store_ps(float * p,__m128 a)2531*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_store_ps(float *p, __m128 a)
2532*35ffd701SAndroid Build Coastguard Worker {
2533*35ffd701SAndroid Build Coastguard Worker vst1q_f32(p, vreinterpretq_f32_m128(a));
2534*35ffd701SAndroid Build Coastguard Worker }
2535*35ffd701SAndroid Build Coastguard Worker
2536*35ffd701SAndroid Build Coastguard Worker // Store the lower single-precision (32-bit) floating-point element from a into
2537*35ffd701SAndroid Build Coastguard Worker // 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte
2538*35ffd701SAndroid Build Coastguard Worker // boundary or a general-protection exception may be generated.
2539*35ffd701SAndroid Build Coastguard Worker //
2540*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+31:mem_addr] := a[31:0]
2541*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+63:mem_addr+32] := a[31:0]
2542*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+95:mem_addr+64] := a[31:0]
2543*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+127:mem_addr+96] := a[31:0]
2544*35ffd701SAndroid Build Coastguard Worker //
2545*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_ps1
_mm_store_ps1(float * p,__m128 a)2546*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_store_ps1(float *p, __m128 a)
2547*35ffd701SAndroid Build Coastguard Worker {
2548*35ffd701SAndroid Build Coastguard Worker float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0);
2549*35ffd701SAndroid Build Coastguard Worker vst1q_f32(p, vdupq_n_f32(a0));
2550*35ffd701SAndroid Build Coastguard Worker }
2551*35ffd701SAndroid Build Coastguard Worker
2552*35ffd701SAndroid Build Coastguard Worker // Stores the lower single - precision, floating - point value.
2553*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx
_mm_store_ss(float * p,__m128 a)2554*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_store_ss(float *p, __m128 a)
2555*35ffd701SAndroid Build Coastguard Worker {
2556*35ffd701SAndroid Build Coastguard Worker vst1q_lane_f32(p, vreinterpretq_f32_m128(a), 0);
2557*35ffd701SAndroid Build Coastguard Worker }
2558*35ffd701SAndroid Build Coastguard Worker
2559*35ffd701SAndroid Build Coastguard Worker // Store the lower single-precision (32-bit) floating-point element from a into
2560*35ffd701SAndroid Build Coastguard Worker // 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte
2561*35ffd701SAndroid Build Coastguard Worker // boundary or a general-protection exception may be generated.
2562*35ffd701SAndroid Build Coastguard Worker //
2563*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+31:mem_addr] := a[31:0]
2564*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+63:mem_addr+32] := a[31:0]
2565*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+95:mem_addr+64] := a[31:0]
2566*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+127:mem_addr+96] := a[31:0]
2567*35ffd701SAndroid Build Coastguard Worker //
2568*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store1_ps
2569*35ffd701SAndroid Build Coastguard Worker #define _mm_store1_ps _mm_store_ps1
2570*35ffd701SAndroid Build Coastguard Worker
2571*35ffd701SAndroid Build Coastguard Worker // Stores the upper two single-precision, floating-point values of a to the
2572*35ffd701SAndroid Build Coastguard Worker // address p.
2573*35ffd701SAndroid Build Coastguard Worker //
2574*35ffd701SAndroid Build Coastguard Worker // *p0 := a2
2575*35ffd701SAndroid Build Coastguard Worker // *p1 := a3
2576*35ffd701SAndroid Build Coastguard Worker //
2577*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/a7525fs8(v%3dvs.90).aspx
_mm_storeh_pi(__m64 * p,__m128 a)2578*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storeh_pi(__m64 *p, __m128 a)
2579*35ffd701SAndroid Build Coastguard Worker {
2580*35ffd701SAndroid Build Coastguard Worker *p = vreinterpret_m64_f32(vget_high_f32(a));
2581*35ffd701SAndroid Build Coastguard Worker }
2582*35ffd701SAndroid Build Coastguard Worker
2583*35ffd701SAndroid Build Coastguard Worker // Stores the lower two single-precision floating point values of a to the
2584*35ffd701SAndroid Build Coastguard Worker // address p.
2585*35ffd701SAndroid Build Coastguard Worker //
2586*35ffd701SAndroid Build Coastguard Worker // *p0 := a0
2587*35ffd701SAndroid Build Coastguard Worker // *p1 := a1
2588*35ffd701SAndroid Build Coastguard Worker //
2589*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/h54t98ks(v=vs.90).aspx
_mm_storel_pi(__m64 * p,__m128 a)2590*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storel_pi(__m64 *p, __m128 a)
2591*35ffd701SAndroid Build Coastguard Worker {
2592*35ffd701SAndroid Build Coastguard Worker *p = vreinterpret_m64_f32(vget_low_f32(a));
2593*35ffd701SAndroid Build Coastguard Worker }
2594*35ffd701SAndroid Build Coastguard Worker
2595*35ffd701SAndroid Build Coastguard Worker // Store 4 single-precision (32-bit) floating-point elements from a into memory
2596*35ffd701SAndroid Build Coastguard Worker // in reverse order. mem_addr must be aligned on a 16-byte boundary or a
2597*35ffd701SAndroid Build Coastguard Worker // general-protection exception may be generated.
2598*35ffd701SAndroid Build Coastguard Worker //
2599*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+31:mem_addr] := a[127:96]
2600*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+63:mem_addr+32] := a[95:64]
2601*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+95:mem_addr+64] := a[63:32]
2602*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+127:mem_addr+96] := a[31:0]
2603*35ffd701SAndroid Build Coastguard Worker //
2604*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_ps
_mm_storer_ps(float * p,__m128 a)2605*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storer_ps(float *p, __m128 a)
2606*35ffd701SAndroid Build Coastguard Worker {
2607*35ffd701SAndroid Build Coastguard Worker float32x4_t tmp = vrev64q_f32(vreinterpretq_f32_m128(a));
2608*35ffd701SAndroid Build Coastguard Worker float32x4_t rev = vextq_f32(tmp, tmp, 2);
2609*35ffd701SAndroid Build Coastguard Worker vst1q_f32(p, rev);
2610*35ffd701SAndroid Build Coastguard Worker }
2611*35ffd701SAndroid Build Coastguard Worker
2612*35ffd701SAndroid Build Coastguard Worker // Stores four single-precision, floating-point values.
2613*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/44e30x22(v=vs.100).aspx
_mm_storeu_ps(float * p,__m128 a)2614*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storeu_ps(float *p, __m128 a)
2615*35ffd701SAndroid Build Coastguard Worker {
2616*35ffd701SAndroid Build Coastguard Worker vst1q_f32(p, vreinterpretq_f32_m128(a));
2617*35ffd701SAndroid Build Coastguard Worker }
2618*35ffd701SAndroid Build Coastguard Worker
2619*35ffd701SAndroid Build Coastguard Worker // Stores 16-bits of integer data a at the address p.
2620*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si16
_mm_storeu_si16(void * p,__m128i a)2621*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storeu_si16(void *p, __m128i a)
2622*35ffd701SAndroid Build Coastguard Worker {
2623*35ffd701SAndroid Build Coastguard Worker vst1q_lane_s16((int16_t *) p, vreinterpretq_s16_m128i(a), 0);
2624*35ffd701SAndroid Build Coastguard Worker }
2625*35ffd701SAndroid Build Coastguard Worker
2626*35ffd701SAndroid Build Coastguard Worker // Stores 64-bits of integer data a at the address p.
2627*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si64
_mm_storeu_si64(void * p,__m128i a)2628*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storeu_si64(void *p, __m128i a)
2629*35ffd701SAndroid Build Coastguard Worker {
2630*35ffd701SAndroid Build Coastguard Worker vst1q_lane_s64((int64_t *) p, vreinterpretq_s64_m128i(a), 0);
2631*35ffd701SAndroid Build Coastguard Worker }
2632*35ffd701SAndroid Build Coastguard Worker
2633*35ffd701SAndroid Build Coastguard Worker // Store 64-bits of integer data from a into memory using a non-temporal memory
2634*35ffd701SAndroid Build Coastguard Worker // hint.
2635*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pi
_mm_stream_pi(__m64 * p,__m64 a)2636*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_stream_pi(__m64 *p, __m64 a)
2637*35ffd701SAndroid Build Coastguard Worker {
2638*35ffd701SAndroid Build Coastguard Worker vst1_s64((int64_t *) p, vreinterpret_s64_m64(a));
2639*35ffd701SAndroid Build Coastguard Worker }
2640*35ffd701SAndroid Build Coastguard Worker
2641*35ffd701SAndroid Build Coastguard Worker // Store 128-bits (composed of 4 packed single-precision (32-bit) floating-
2642*35ffd701SAndroid Build Coastguard Worker // point elements) from a into memory using a non-temporal memory hint.
2643*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_ps
_mm_stream_ps(float * p,__m128 a)2644*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_stream_ps(float *p, __m128 a)
2645*35ffd701SAndroid Build Coastguard Worker {
2646*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_nontemporal_store)
2647*35ffd701SAndroid Build Coastguard Worker __builtin_nontemporal_store(a, (float32x4_t *) p);
2648*35ffd701SAndroid Build Coastguard Worker #else
2649*35ffd701SAndroid Build Coastguard Worker vst1q_f32(p, vreinterpretq_f32_m128(a));
2650*35ffd701SAndroid Build Coastguard Worker #endif
2651*35ffd701SAndroid Build Coastguard Worker }
2652*35ffd701SAndroid Build Coastguard Worker
2653*35ffd701SAndroid Build Coastguard Worker // Subtracts the four single-precision, floating-point values of a and b.
2654*35ffd701SAndroid Build Coastguard Worker //
2655*35ffd701SAndroid Build Coastguard Worker // r0 := a0 - b0
2656*35ffd701SAndroid Build Coastguard Worker // r1 := a1 - b1
2657*35ffd701SAndroid Build Coastguard Worker // r2 := a2 - b2
2658*35ffd701SAndroid Build Coastguard Worker // r3 := a3 - b3
2659*35ffd701SAndroid Build Coastguard Worker //
2660*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/1zad2k61(v=vs.100).aspx
_mm_sub_ps(__m128 a,__m128 b)2661*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b)
2662*35ffd701SAndroid Build Coastguard Worker {
2663*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
2664*35ffd701SAndroid Build Coastguard Worker vsubq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
2665*35ffd701SAndroid Build Coastguard Worker }
2666*35ffd701SAndroid Build Coastguard Worker
2667*35ffd701SAndroid Build Coastguard Worker // Subtract the lower single-precision (32-bit) floating-point element in b from
2668*35ffd701SAndroid Build Coastguard Worker // the lower single-precision (32-bit) floating-point element in a, store the
2669*35ffd701SAndroid Build Coastguard Worker // result in the lower element of dst, and copy the upper 3 packed elements from
2670*35ffd701SAndroid Build Coastguard Worker // a to the upper elements of dst.
2671*35ffd701SAndroid Build Coastguard Worker //
2672*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := a[31:0] - b[31:0]
2673*35ffd701SAndroid Build Coastguard Worker // dst[127:32] := a[127:32]
2674*35ffd701SAndroid Build Coastguard Worker //
2675*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_ss
_mm_sub_ss(__m128 a,__m128 b)2676*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_sub_ss(__m128 a, __m128 b)
2677*35ffd701SAndroid Build Coastguard Worker {
2678*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_sub_ps(a, b));
2679*35ffd701SAndroid Build Coastguard Worker }
2680*35ffd701SAndroid Build Coastguard Worker
2681*35ffd701SAndroid Build Coastguard Worker // Macro: Transpose the 4x4 matrix formed by the 4 rows of single-precision
2682*35ffd701SAndroid Build Coastguard Worker // (32-bit) floating-point elements in row0, row1, row2, and row3, and store the
2683*35ffd701SAndroid Build Coastguard Worker // transposed matrix in these vectors (row0 now contains column 0, etc.).
2684*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=MM_TRANSPOSE4_PS
2685*35ffd701SAndroid Build Coastguard Worker #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \
2686*35ffd701SAndroid Build Coastguard Worker do { \
2687*35ffd701SAndroid Build Coastguard Worker float32x4x2_t ROW01 = vtrnq_f32(row0, row1); \
2688*35ffd701SAndroid Build Coastguard Worker float32x4x2_t ROW23 = vtrnq_f32(row2, row3); \
2689*35ffd701SAndroid Build Coastguard Worker row0 = vcombine_f32(vget_low_f32(ROW01.val[0]), \
2690*35ffd701SAndroid Build Coastguard Worker vget_low_f32(ROW23.val[0])); \
2691*35ffd701SAndroid Build Coastguard Worker row1 = vcombine_f32(vget_low_f32(ROW01.val[1]), \
2692*35ffd701SAndroid Build Coastguard Worker vget_low_f32(ROW23.val[1])); \
2693*35ffd701SAndroid Build Coastguard Worker row2 = vcombine_f32(vget_high_f32(ROW01.val[0]), \
2694*35ffd701SAndroid Build Coastguard Worker vget_high_f32(ROW23.val[0])); \
2695*35ffd701SAndroid Build Coastguard Worker row3 = vcombine_f32(vget_high_f32(ROW01.val[1]), \
2696*35ffd701SAndroid Build Coastguard Worker vget_high_f32(ROW23.val[1])); \
2697*35ffd701SAndroid Build Coastguard Worker } while (0)
2698*35ffd701SAndroid Build Coastguard Worker
2699*35ffd701SAndroid Build Coastguard Worker // according to the documentation, these intrinsics behave the same as the
2700*35ffd701SAndroid Build Coastguard Worker // non-'u' versions. We'll just alias them here.
2701*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomieq_ss _mm_comieq_ss
2702*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomige_ss _mm_comige_ss
2703*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomigt_ss _mm_comigt_ss
2704*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomile_ss _mm_comile_ss
2705*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomilt_ss _mm_comilt_ss
2706*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomineq_ss _mm_comineq_ss
2707*35ffd701SAndroid Build Coastguard Worker
2708*35ffd701SAndroid Build Coastguard Worker // Return vector of type __m128i with undefined elements.
2709*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_undefined_si128
_mm_undefined_si128(void)2710*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_undefined_si128(void)
2711*35ffd701SAndroid Build Coastguard Worker {
2712*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
2713*35ffd701SAndroid Build Coastguard Worker #pragma GCC diagnostic push
2714*35ffd701SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wuninitialized"
2715*35ffd701SAndroid Build Coastguard Worker #endif
2716*35ffd701SAndroid Build Coastguard Worker __m128i a;
2717*35ffd701SAndroid Build Coastguard Worker return a;
2718*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
2719*35ffd701SAndroid Build Coastguard Worker #pragma GCC diagnostic pop
2720*35ffd701SAndroid Build Coastguard Worker #endif
2721*35ffd701SAndroid Build Coastguard Worker }
2722*35ffd701SAndroid Build Coastguard Worker
2723*35ffd701SAndroid Build Coastguard Worker // Return vector of type __m128 with undefined elements.
2724*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_ps
_mm_undefined_ps(void)2725*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_undefined_ps(void)
2726*35ffd701SAndroid Build Coastguard Worker {
2727*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
2728*35ffd701SAndroid Build Coastguard Worker #pragma GCC diagnostic push
2729*35ffd701SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wuninitialized"
2730*35ffd701SAndroid Build Coastguard Worker #endif
2731*35ffd701SAndroid Build Coastguard Worker __m128 a;
2732*35ffd701SAndroid Build Coastguard Worker return a;
2733*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
2734*35ffd701SAndroid Build Coastguard Worker #pragma GCC diagnostic pop
2735*35ffd701SAndroid Build Coastguard Worker #endif
2736*35ffd701SAndroid Build Coastguard Worker }
2737*35ffd701SAndroid Build Coastguard Worker
2738*35ffd701SAndroid Build Coastguard Worker // Selects and interleaves the upper two single-precision, floating-point values
2739*35ffd701SAndroid Build Coastguard Worker // from a and b.
2740*35ffd701SAndroid Build Coastguard Worker //
2741*35ffd701SAndroid Build Coastguard Worker // r0 := a2
2742*35ffd701SAndroid Build Coastguard Worker // r1 := b2
2743*35ffd701SAndroid Build Coastguard Worker // r2 := a3
2744*35ffd701SAndroid Build Coastguard Worker // r3 := b3
2745*35ffd701SAndroid Build Coastguard Worker //
2746*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/skccxx7d%28v=vs.90%29.aspx
_mm_unpackhi_ps(__m128 a,__m128 b)2747*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b)
2748*35ffd701SAndroid Build Coastguard Worker {
2749*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
2750*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
2751*35ffd701SAndroid Build Coastguard Worker vzip2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
2752*35ffd701SAndroid Build Coastguard Worker #else
2753*35ffd701SAndroid Build Coastguard Worker float32x2_t a1 = vget_high_f32(vreinterpretq_f32_m128(a));
2754*35ffd701SAndroid Build Coastguard Worker float32x2_t b1 = vget_high_f32(vreinterpretq_f32_m128(b));
2755*35ffd701SAndroid Build Coastguard Worker float32x2x2_t result = vzip_f32(a1, b1);
2756*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1]));
2757*35ffd701SAndroid Build Coastguard Worker #endif
2758*35ffd701SAndroid Build Coastguard Worker }
2759*35ffd701SAndroid Build Coastguard Worker
2760*35ffd701SAndroid Build Coastguard Worker // Selects and interleaves the lower two single-precision, floating-point values
2761*35ffd701SAndroid Build Coastguard Worker // from a and b.
2762*35ffd701SAndroid Build Coastguard Worker //
2763*35ffd701SAndroid Build Coastguard Worker // r0 := a0
2764*35ffd701SAndroid Build Coastguard Worker // r1 := b0
2765*35ffd701SAndroid Build Coastguard Worker // r2 := a1
2766*35ffd701SAndroid Build Coastguard Worker // r3 := b1
2767*35ffd701SAndroid Build Coastguard Worker //
2768*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/25st103b%28v=vs.90%29.aspx
_mm_unpacklo_ps(__m128 a,__m128 b)2769*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b)
2770*35ffd701SAndroid Build Coastguard Worker {
2771*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
2772*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
2773*35ffd701SAndroid Build Coastguard Worker vzip1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
2774*35ffd701SAndroid Build Coastguard Worker #else
2775*35ffd701SAndroid Build Coastguard Worker float32x2_t a1 = vget_low_f32(vreinterpretq_f32_m128(a));
2776*35ffd701SAndroid Build Coastguard Worker float32x2_t b1 = vget_low_f32(vreinterpretq_f32_m128(b));
2777*35ffd701SAndroid Build Coastguard Worker float32x2x2_t result = vzip_f32(a1, b1);
2778*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1]));
2779*35ffd701SAndroid Build Coastguard Worker #endif
2780*35ffd701SAndroid Build Coastguard Worker }
2781*35ffd701SAndroid Build Coastguard Worker
2782*35ffd701SAndroid Build Coastguard Worker // Computes bitwise EXOR (exclusive-or) of the four single-precision,
2783*35ffd701SAndroid Build Coastguard Worker // floating-point values of a and b.
2784*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/ss6k3wk8(v=vs.100).aspx
_mm_xor_ps(__m128 a,__m128 b)2785*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_xor_ps(__m128 a, __m128 b)
2786*35ffd701SAndroid Build Coastguard Worker {
2787*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_s32(
2788*35ffd701SAndroid Build Coastguard Worker veorq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b)));
2789*35ffd701SAndroid Build Coastguard Worker }
2790*35ffd701SAndroid Build Coastguard Worker
2791*35ffd701SAndroid Build Coastguard Worker /* SSE2 */
2792*35ffd701SAndroid Build Coastguard Worker
2793*35ffd701SAndroid Build Coastguard Worker // Adds the 8 signed or unsigned 16-bit integers in a to the 8 signed or
2794*35ffd701SAndroid Build Coastguard Worker // unsigned 16-bit integers in b.
2795*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/fceha5k4(v=vs.100).aspx
_mm_add_epi16(__m128i a,__m128i b)2796*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_add_epi16(__m128i a, __m128i b)
2797*35ffd701SAndroid Build Coastguard Worker {
2798*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
2799*35ffd701SAndroid Build Coastguard Worker vaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
2800*35ffd701SAndroid Build Coastguard Worker }
2801*35ffd701SAndroid Build Coastguard Worker
2802*35ffd701SAndroid Build Coastguard Worker // Adds the 4 signed or unsigned 32-bit integers in a to the 4 signed or
2803*35ffd701SAndroid Build Coastguard Worker // unsigned 32-bit integers in b.
2804*35ffd701SAndroid Build Coastguard Worker //
2805*35ffd701SAndroid Build Coastguard Worker // r0 := a0 + b0
2806*35ffd701SAndroid Build Coastguard Worker // r1 := a1 + b1
2807*35ffd701SAndroid Build Coastguard Worker // r2 := a2 + b2
2808*35ffd701SAndroid Build Coastguard Worker // r3 := a3 + b3
2809*35ffd701SAndroid Build Coastguard Worker //
2810*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx
_mm_add_epi32(__m128i a,__m128i b)2811*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b)
2812*35ffd701SAndroid Build Coastguard Worker {
2813*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
2814*35ffd701SAndroid Build Coastguard Worker vaddq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
2815*35ffd701SAndroid Build Coastguard Worker }
2816*35ffd701SAndroid Build Coastguard Worker
2817*35ffd701SAndroid Build Coastguard Worker // Adds the 4 signed or unsigned 64-bit integers in a to the 4 signed or
2818*35ffd701SAndroid Build Coastguard Worker // unsigned 32-bit integers in b.
2819*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx
_mm_add_epi64(__m128i a,__m128i b)2820*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_add_epi64(__m128i a, __m128i b)
2821*35ffd701SAndroid Build Coastguard Worker {
2822*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(
2823*35ffd701SAndroid Build Coastguard Worker vaddq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b)));
2824*35ffd701SAndroid Build Coastguard Worker }
2825*35ffd701SAndroid Build Coastguard Worker
2826*35ffd701SAndroid Build Coastguard Worker // Adds the 16 signed or unsigned 8-bit integers in a to the 16 signed or
2827*35ffd701SAndroid Build Coastguard Worker // unsigned 8-bit integers in b.
2828*35ffd701SAndroid Build Coastguard Worker // https://technet.microsoft.com/en-us/subscriptions/yc7tcyzs(v=vs.90)
_mm_add_epi8(__m128i a,__m128i b)2829*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_add_epi8(__m128i a, __m128i b)
2830*35ffd701SAndroid Build Coastguard Worker {
2831*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
2832*35ffd701SAndroid Build Coastguard Worker vaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
2833*35ffd701SAndroid Build Coastguard Worker }
2834*35ffd701SAndroid Build Coastguard Worker
2835*35ffd701SAndroid Build Coastguard Worker // Add packed double-precision (64-bit) floating-point elements in a and b, and
2836*35ffd701SAndroid Build Coastguard Worker // store the results in dst.
2837*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_pd
_mm_add_pd(__m128d a,__m128d b)2838*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_add_pd(__m128d a, __m128d b)
2839*35ffd701SAndroid Build Coastguard Worker {
2840*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
2841*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
2842*35ffd701SAndroid Build Coastguard Worker vaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
2843*35ffd701SAndroid Build Coastguard Worker #else
2844*35ffd701SAndroid Build Coastguard Worker double *da = (double *) &a;
2845*35ffd701SAndroid Build Coastguard Worker double *db = (double *) &b;
2846*35ffd701SAndroid Build Coastguard Worker double c[2];
2847*35ffd701SAndroid Build Coastguard Worker c[0] = da[0] + db[0];
2848*35ffd701SAndroid Build Coastguard Worker c[1] = da[1] + db[1];
2849*35ffd701SAndroid Build Coastguard Worker return vld1q_f32((float32_t *) c);
2850*35ffd701SAndroid Build Coastguard Worker #endif
2851*35ffd701SAndroid Build Coastguard Worker }
2852*35ffd701SAndroid Build Coastguard Worker
2853*35ffd701SAndroid Build Coastguard Worker // Add the lower double-precision (64-bit) floating-point element in a and b,
2854*35ffd701SAndroid Build Coastguard Worker // store the result in the lower element of dst, and copy the upper element from
2855*35ffd701SAndroid Build Coastguard Worker // a to the upper element of dst.
2856*35ffd701SAndroid Build Coastguard Worker //
2857*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0] + b[63:0]
2858*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := a[127:64]
2859*35ffd701SAndroid Build Coastguard Worker //
2860*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_sd
_mm_add_sd(__m128d a,__m128d b)2861*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_add_sd(__m128d a, __m128d b)
2862*35ffd701SAndroid Build Coastguard Worker {
2863*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
2864*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_add_pd(a, b));
2865*35ffd701SAndroid Build Coastguard Worker #else
2866*35ffd701SAndroid Build Coastguard Worker double *da = (double *) &a;
2867*35ffd701SAndroid Build Coastguard Worker double *db = (double *) &b;
2868*35ffd701SAndroid Build Coastguard Worker double c[2];
2869*35ffd701SAndroid Build Coastguard Worker c[0] = da[0] + db[0];
2870*35ffd701SAndroid Build Coastguard Worker c[1] = da[1];
2871*35ffd701SAndroid Build Coastguard Worker return vld1q_f32((float32_t *) c);
2872*35ffd701SAndroid Build Coastguard Worker #endif
2873*35ffd701SAndroid Build Coastguard Worker }
2874*35ffd701SAndroid Build Coastguard Worker
2875*35ffd701SAndroid Build Coastguard Worker // Add 64-bit integers a and b, and store the result in dst.
2876*35ffd701SAndroid Build Coastguard Worker //
2877*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0] + b[63:0]
2878*35ffd701SAndroid Build Coastguard Worker //
2879*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_si64
_mm_add_si64(__m64 a,__m64 b)2880*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_add_si64(__m64 a, __m64 b)
2881*35ffd701SAndroid Build Coastguard Worker {
2882*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s64(
2883*35ffd701SAndroid Build Coastguard Worker vadd_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b)));
2884*35ffd701SAndroid Build Coastguard Worker }
2885*35ffd701SAndroid Build Coastguard Worker
2886*35ffd701SAndroid Build Coastguard Worker // Adds the 8 signed 16-bit integers in a to the 8 signed 16-bit integers in b
2887*35ffd701SAndroid Build Coastguard Worker // and saturates.
2888*35ffd701SAndroid Build Coastguard Worker //
2889*35ffd701SAndroid Build Coastguard Worker // r0 := SignedSaturate(a0 + b0)
2890*35ffd701SAndroid Build Coastguard Worker // r1 := SignedSaturate(a1 + b1)
2891*35ffd701SAndroid Build Coastguard Worker // ...
2892*35ffd701SAndroid Build Coastguard Worker // r7 := SignedSaturate(a7 + b7)
2893*35ffd701SAndroid Build Coastguard Worker //
2894*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/1a306ef8(v=vs.100).aspx
_mm_adds_epi16(__m128i a,__m128i b)2895*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_adds_epi16(__m128i a, __m128i b)
2896*35ffd701SAndroid Build Coastguard Worker {
2897*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
2898*35ffd701SAndroid Build Coastguard Worker vqaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
2899*35ffd701SAndroid Build Coastguard Worker }
2900*35ffd701SAndroid Build Coastguard Worker
2901*35ffd701SAndroid Build Coastguard Worker // Add packed signed 8-bit integers in a and b using saturation, and store the
2902*35ffd701SAndroid Build Coastguard Worker // results in dst.
2903*35ffd701SAndroid Build Coastguard Worker //
2904*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 15
2905*35ffd701SAndroid Build Coastguard Worker // i := j*8
2906*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := Saturate8( a[i+7:i] + b[i+7:i] )
2907*35ffd701SAndroid Build Coastguard Worker // ENDFOR
2908*35ffd701SAndroid Build Coastguard Worker //
2909*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epi8
_mm_adds_epi8(__m128i a,__m128i b)2910*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_adds_epi8(__m128i a, __m128i b)
2911*35ffd701SAndroid Build Coastguard Worker {
2912*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
2913*35ffd701SAndroid Build Coastguard Worker vqaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
2914*35ffd701SAndroid Build Coastguard Worker }
2915*35ffd701SAndroid Build Coastguard Worker
2916*35ffd701SAndroid Build Coastguard Worker // Add packed unsigned 16-bit integers in a and b using saturation, and store
2917*35ffd701SAndroid Build Coastguard Worker // the results in dst.
2918*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epu16
_mm_adds_epu16(__m128i a,__m128i b)2919*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_adds_epu16(__m128i a, __m128i b)
2920*35ffd701SAndroid Build Coastguard Worker {
2921*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(
2922*35ffd701SAndroid Build Coastguard Worker vqaddq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b)));
2923*35ffd701SAndroid Build Coastguard Worker }
2924*35ffd701SAndroid Build Coastguard Worker
2925*35ffd701SAndroid Build Coastguard Worker // Adds the 16 unsigned 8-bit integers in a to the 16 unsigned 8-bit integers in
2926*35ffd701SAndroid Build Coastguard Worker // b and saturates..
2927*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/9hahyddy(v=vs.100).aspx
_mm_adds_epu8(__m128i a,__m128i b)2928*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_adds_epu8(__m128i a, __m128i b)
2929*35ffd701SAndroid Build Coastguard Worker {
2930*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
2931*35ffd701SAndroid Build Coastguard Worker vqaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b)));
2932*35ffd701SAndroid Build Coastguard Worker }
2933*35ffd701SAndroid Build Coastguard Worker
2934*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise AND of packed double-precision (64-bit) floating-point
2935*35ffd701SAndroid Build Coastguard Worker // elements in a and b, and store the results in dst.
2936*35ffd701SAndroid Build Coastguard Worker //
2937*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
2938*35ffd701SAndroid Build Coastguard Worker // i := j*64
2939*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := a[i+63:i] AND b[i+63:i]
2940*35ffd701SAndroid Build Coastguard Worker // ENDFOR
2941*35ffd701SAndroid Build Coastguard Worker //
2942*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_and_pd
_mm_and_pd(__m128d a,__m128d b)2943*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_and_pd(__m128d a, __m128d b)
2944*35ffd701SAndroid Build Coastguard Worker {
2945*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(
2946*35ffd701SAndroid Build Coastguard Worker vandq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b)));
2947*35ffd701SAndroid Build Coastguard Worker }
2948*35ffd701SAndroid Build Coastguard Worker
2949*35ffd701SAndroid Build Coastguard Worker // Computes the bitwise AND of the 128-bit value in a and the 128-bit value in
2950*35ffd701SAndroid Build Coastguard Worker // b.
2951*35ffd701SAndroid Build Coastguard Worker //
2952*35ffd701SAndroid Build Coastguard Worker // r := a & b
2953*35ffd701SAndroid Build Coastguard Worker //
2954*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/6d1txsa8(v=vs.100).aspx
_mm_and_si128(__m128i a,__m128i b)2955*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_and_si128(__m128i a, __m128i b)
2956*35ffd701SAndroid Build Coastguard Worker {
2957*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
2958*35ffd701SAndroid Build Coastguard Worker vandq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
2959*35ffd701SAndroid Build Coastguard Worker }
2960*35ffd701SAndroid Build Coastguard Worker
2961*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise NOT of packed double-precision (64-bit) floating-point
2962*35ffd701SAndroid Build Coastguard Worker // elements in a and then AND with b, and store the results in dst.
2963*35ffd701SAndroid Build Coastguard Worker //
2964*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
2965*35ffd701SAndroid Build Coastguard Worker // i := j*64
2966*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := ((NOT a[i+63:i]) AND b[i+63:i])
2967*35ffd701SAndroid Build Coastguard Worker // ENDFOR
2968*35ffd701SAndroid Build Coastguard Worker //
2969*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_andnot_pd
_mm_andnot_pd(__m128d a,__m128d b)2970*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_andnot_pd(__m128d a, __m128d b)
2971*35ffd701SAndroid Build Coastguard Worker {
2972*35ffd701SAndroid Build Coastguard Worker // *NOTE* argument swap
2973*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(
2974*35ffd701SAndroid Build Coastguard Worker vbicq_s64(vreinterpretq_s64_m128d(b), vreinterpretq_s64_m128d(a)));
2975*35ffd701SAndroid Build Coastguard Worker }
2976*35ffd701SAndroid Build Coastguard Worker
2977*35ffd701SAndroid Build Coastguard Worker // Computes the bitwise AND of the 128-bit value in b and the bitwise NOT of the
2978*35ffd701SAndroid Build Coastguard Worker // 128-bit value in a.
2979*35ffd701SAndroid Build Coastguard Worker //
2980*35ffd701SAndroid Build Coastguard Worker // r := (~a) & b
2981*35ffd701SAndroid Build Coastguard Worker //
2982*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/1beaceh8(v=vs.100).aspx
_mm_andnot_si128(__m128i a,__m128i b)2983*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_andnot_si128(__m128i a, __m128i b)
2984*35ffd701SAndroid Build Coastguard Worker {
2985*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
2986*35ffd701SAndroid Build Coastguard Worker vbicq_s32(vreinterpretq_s32_m128i(b),
2987*35ffd701SAndroid Build Coastguard Worker vreinterpretq_s32_m128i(a))); // *NOTE* argument swap
2988*35ffd701SAndroid Build Coastguard Worker }
2989*35ffd701SAndroid Build Coastguard Worker
2990*35ffd701SAndroid Build Coastguard Worker // Computes the average of the 8 unsigned 16-bit integers in a and the 8
2991*35ffd701SAndroid Build Coastguard Worker // unsigned 16-bit integers in b and rounds.
2992*35ffd701SAndroid Build Coastguard Worker //
2993*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 + b0) / 2
2994*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 + b1) / 2
2995*35ffd701SAndroid Build Coastguard Worker // ...
2996*35ffd701SAndroid Build Coastguard Worker // r7 := (a7 + b7) / 2
2997*35ffd701SAndroid Build Coastguard Worker //
2998*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/y13ca3c8(v=vs.90).aspx
_mm_avg_epu16(__m128i a,__m128i b)2999*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_avg_epu16(__m128i a, __m128i b)
3000*35ffd701SAndroid Build Coastguard Worker {
3001*35ffd701SAndroid Build Coastguard Worker return (__m128i) vrhaddq_u16(vreinterpretq_u16_m128i(a),
3002*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u16_m128i(b));
3003*35ffd701SAndroid Build Coastguard Worker }
3004*35ffd701SAndroid Build Coastguard Worker
3005*35ffd701SAndroid Build Coastguard Worker // Computes the average of the 16 unsigned 8-bit integers in a and the 16
3006*35ffd701SAndroid Build Coastguard Worker // unsigned 8-bit integers in b and rounds.
3007*35ffd701SAndroid Build Coastguard Worker //
3008*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 + b0) / 2
3009*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 + b1) / 2
3010*35ffd701SAndroid Build Coastguard Worker // ...
3011*35ffd701SAndroid Build Coastguard Worker // r15 := (a15 + b15) / 2
3012*35ffd701SAndroid Build Coastguard Worker //
3013*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/8zwh554a(v%3dvs.90).aspx
_mm_avg_epu8(__m128i a,__m128i b)3014*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_avg_epu8(__m128i a, __m128i b)
3015*35ffd701SAndroid Build Coastguard Worker {
3016*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
3017*35ffd701SAndroid Build Coastguard Worker vrhaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b)));
3018*35ffd701SAndroid Build Coastguard Worker }
3019*35ffd701SAndroid Build Coastguard Worker
3020*35ffd701SAndroid Build Coastguard Worker // Shift a left by imm8 bytes while shifting in zeros, and store the results in
3021*35ffd701SAndroid Build Coastguard Worker // dst.
3022*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_bslli_si128
3023*35ffd701SAndroid Build Coastguard Worker #define _mm_bslli_si128(a, imm) _mm_slli_si128(a, imm)
3024*35ffd701SAndroid Build Coastguard Worker
3025*35ffd701SAndroid Build Coastguard Worker // Shift a right by imm8 bytes while shifting in zeros, and store the results in
3026*35ffd701SAndroid Build Coastguard Worker // dst.
3027*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_bsrli_si128
3028*35ffd701SAndroid Build Coastguard Worker #define _mm_bsrli_si128(a, imm) _mm_srli_si128(a, imm)
3029*35ffd701SAndroid Build Coastguard Worker
3030*35ffd701SAndroid Build Coastguard Worker // Cast vector of type __m128d to type __m128. This intrinsic is only used for
3031*35ffd701SAndroid Build Coastguard Worker // compilation and does not generate any instructions, thus it has zero latency.
3032*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_ps
_mm_castpd_ps(__m128d a)3033*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_castpd_ps(__m128d a)
3034*35ffd701SAndroid Build Coastguard Worker {
3035*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_s64(vreinterpretq_s64_m128d(a));
3036*35ffd701SAndroid Build Coastguard Worker }
3037*35ffd701SAndroid Build Coastguard Worker
3038*35ffd701SAndroid Build Coastguard Worker // Cast vector of type __m128d to type __m128i. This intrinsic is only used for
3039*35ffd701SAndroid Build Coastguard Worker // compilation and does not generate any instructions, thus it has zero latency.
3040*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_si128
_mm_castpd_si128(__m128d a)3041*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_castpd_si128(__m128d a)
3042*35ffd701SAndroid Build Coastguard Worker {
3043*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vreinterpretq_s64_m128d(a));
3044*35ffd701SAndroid Build Coastguard Worker }
3045*35ffd701SAndroid Build Coastguard Worker
3046*35ffd701SAndroid Build Coastguard Worker // Cast vector of type __m128 to type __m128d. This intrinsic is only used for
3047*35ffd701SAndroid Build Coastguard Worker // compilation and does not generate any instructions, thus it has zero latency.
3048*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castps_pd
_mm_castps_pd(__m128 a)3049*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_castps_pd(__m128 a)
3050*35ffd701SAndroid Build Coastguard Worker {
3051*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s32(vreinterpretq_s32_m128(a));
3052*35ffd701SAndroid Build Coastguard Worker }
3053*35ffd701SAndroid Build Coastguard Worker
3054*35ffd701SAndroid Build Coastguard Worker // Applies a type cast to reinterpret four 32-bit floating point values passed
3055*35ffd701SAndroid Build Coastguard Worker // in as a 128-bit parameter as packed 32-bit integers.
3056*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/bb514099.aspx
_mm_castps_si128(__m128 a)3057*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_castps_si128(__m128 a)
3058*35ffd701SAndroid Build Coastguard Worker {
3059*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vreinterpretq_s32_m128(a));
3060*35ffd701SAndroid Build Coastguard Worker }
3061*35ffd701SAndroid Build Coastguard Worker
3062*35ffd701SAndroid Build Coastguard Worker // Cast vector of type __m128i to type __m128d. This intrinsic is only used for
3063*35ffd701SAndroid Build Coastguard Worker // compilation and does not generate any instructions, thus it has zero latency.
3064*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castsi128_pd
_mm_castsi128_pd(__m128i a)3065*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_castsi128_pd(__m128i a)
3066*35ffd701SAndroid Build Coastguard Worker {
3067*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3068*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vreinterpretq_f64_m128i(a));
3069*35ffd701SAndroid Build Coastguard Worker #else
3070*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f32(vreinterpretq_f32_m128i(a));
3071*35ffd701SAndroid Build Coastguard Worker #endif
3072*35ffd701SAndroid Build Coastguard Worker }
3073*35ffd701SAndroid Build Coastguard Worker
3074*35ffd701SAndroid Build Coastguard Worker // Applies a type cast to reinterpret four 32-bit integers passed in as a
3075*35ffd701SAndroid Build Coastguard Worker // 128-bit parameter as packed 32-bit floating point values.
3076*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/bb514029.aspx
_mm_castsi128_ps(__m128i a)3077*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_castsi128_ps(__m128i a)
3078*35ffd701SAndroid Build Coastguard Worker {
3079*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_s32(vreinterpretq_s32_m128i(a));
3080*35ffd701SAndroid Build Coastguard Worker }
3081*35ffd701SAndroid Build Coastguard Worker
3082*35ffd701SAndroid Build Coastguard Worker // Cache line containing p is flushed and invalidated from all caches in the
3083*35ffd701SAndroid Build Coastguard Worker // coherency domain. :
3084*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/ba08y07y(v=vs.100).aspx
_mm_clflush(void const * p)3085*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_clflush(void const *p)
3086*35ffd701SAndroid Build Coastguard Worker {
3087*35ffd701SAndroid Build Coastguard Worker (void) p;
3088*35ffd701SAndroid Build Coastguard Worker // no corollary for Neon?
3089*35ffd701SAndroid Build Coastguard Worker }
3090*35ffd701SAndroid Build Coastguard Worker
3091*35ffd701SAndroid Build Coastguard Worker // Compares the 8 signed or unsigned 16-bit integers in a and the 8 signed or
3092*35ffd701SAndroid Build Coastguard Worker // unsigned 16-bit integers in b for equality.
3093*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/2ay060te(v=vs.100).aspx
_mm_cmpeq_epi16(__m128i a,__m128i b)3094*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmpeq_epi16(__m128i a, __m128i b)
3095*35ffd701SAndroid Build Coastguard Worker {
3096*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(
3097*35ffd701SAndroid Build Coastguard Worker vceqq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
3098*35ffd701SAndroid Build Coastguard Worker }
3099*35ffd701SAndroid Build Coastguard Worker
3100*35ffd701SAndroid Build Coastguard Worker // Compare packed 32-bit integers in a and b for equality, and store the results
3101*35ffd701SAndroid Build Coastguard Worker // in dst
_mm_cmpeq_epi32(__m128i a,__m128i b)3102*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b)
3103*35ffd701SAndroid Build Coastguard Worker {
3104*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u32(
3105*35ffd701SAndroid Build Coastguard Worker vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
3106*35ffd701SAndroid Build Coastguard Worker }
3107*35ffd701SAndroid Build Coastguard Worker
3108*35ffd701SAndroid Build Coastguard Worker // Compares the 16 signed or unsigned 8-bit integers in a and the 16 signed or
3109*35ffd701SAndroid Build Coastguard Worker // unsigned 8-bit integers in b for equality.
3110*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/windows/desktop/bz5xk21a(v=vs.90).aspx
_mm_cmpeq_epi8(__m128i a,__m128i b)3111*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmpeq_epi8(__m128i a, __m128i b)
3112*35ffd701SAndroid Build Coastguard Worker {
3113*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
3114*35ffd701SAndroid Build Coastguard Worker vceqq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
3115*35ffd701SAndroid Build Coastguard Worker }
3116*35ffd701SAndroid Build Coastguard Worker
3117*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3118*35ffd701SAndroid Build Coastguard Worker // for equality, and store the results in dst.
3119*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_pd
_mm_cmpeq_pd(__m128d a,__m128d b)3120*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpeq_pd(__m128d a, __m128d b)
3121*35ffd701SAndroid Build Coastguard Worker {
3122*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3123*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(
3124*35ffd701SAndroid Build Coastguard Worker vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
3125*35ffd701SAndroid Build Coastguard Worker #else
3126*35ffd701SAndroid Build Coastguard Worker // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi)
3127*35ffd701SAndroid Build Coastguard Worker uint32x4_t cmp =
3128*35ffd701SAndroid Build Coastguard Worker vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b));
3129*35ffd701SAndroid Build Coastguard Worker uint32x4_t swapped = vrev64q_u32(cmp);
3130*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u32(vandq_u32(cmp, swapped));
3131*35ffd701SAndroid Build Coastguard Worker #endif
3132*35ffd701SAndroid Build Coastguard Worker }
3133*35ffd701SAndroid Build Coastguard Worker
3134*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3135*35ffd701SAndroid Build Coastguard Worker // b for equality, store the result in the lower element of dst, and copy the
3136*35ffd701SAndroid Build Coastguard Worker // upper element from a to the upper element of dst.
3137*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_sd
_mm_cmpeq_sd(__m128d a,__m128d b)3138*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpeq_sd(__m128d a, __m128d b)
3139*35ffd701SAndroid Build Coastguard Worker {
3140*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_cmpeq_pd(a, b));
3141*35ffd701SAndroid Build Coastguard Worker }
3142*35ffd701SAndroid Build Coastguard Worker
3143*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3144*35ffd701SAndroid Build Coastguard Worker // for greater-than-or-equal, and store the results in dst.
3145*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_pd
_mm_cmpge_pd(__m128d a,__m128d b)3146*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpge_pd(__m128d a, __m128d b)
3147*35ffd701SAndroid Build Coastguard Worker {
3148*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3149*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(
3150*35ffd701SAndroid Build Coastguard Worker vcgeq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
3151*35ffd701SAndroid Build Coastguard Worker #else
3152*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3153*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3154*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3155*35ffd701SAndroid Build Coastguard Worker uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
3156*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3157*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
3158*35ffd701SAndroid Build Coastguard Worker d[1] = (*(double *) &a1) >= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0);
3159*35ffd701SAndroid Build Coastguard Worker
3160*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3161*35ffd701SAndroid Build Coastguard Worker #endif
3162*35ffd701SAndroid Build Coastguard Worker }
3163*35ffd701SAndroid Build Coastguard Worker
3164*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3165*35ffd701SAndroid Build Coastguard Worker // b for greater-than-or-equal, store the result in the lower element of dst,
3166*35ffd701SAndroid Build Coastguard Worker // and copy the upper element from a to the upper element of dst.
3167*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_sd
_mm_cmpge_sd(__m128d a,__m128d b)3168*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpge_sd(__m128d a, __m128d b)
3169*35ffd701SAndroid Build Coastguard Worker {
3170*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3171*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_cmpge_pd(a, b));
3172*35ffd701SAndroid Build Coastguard Worker #else
3173*35ffd701SAndroid Build Coastguard Worker // expand "_mm_cmpge_pd()" to reduce unnecessary operations
3174*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3175*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3176*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3177*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3178*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
3179*35ffd701SAndroid Build Coastguard Worker d[1] = a1;
3180*35ffd701SAndroid Build Coastguard Worker
3181*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3182*35ffd701SAndroid Build Coastguard Worker #endif
3183*35ffd701SAndroid Build Coastguard Worker }
3184*35ffd701SAndroid Build Coastguard Worker
3185*35ffd701SAndroid Build Coastguard Worker // Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers
3186*35ffd701SAndroid Build Coastguard Worker // in b for greater than.
3187*35ffd701SAndroid Build Coastguard Worker //
3188*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 > b0) ? 0xffff : 0x0
3189*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 > b1) ? 0xffff : 0x0
3190*35ffd701SAndroid Build Coastguard Worker // ...
3191*35ffd701SAndroid Build Coastguard Worker // r7 := (a7 > b7) ? 0xffff : 0x0
3192*35ffd701SAndroid Build Coastguard Worker //
3193*35ffd701SAndroid Build Coastguard Worker // https://technet.microsoft.com/en-us/library/xd43yfsa(v=vs.100).aspx
_mm_cmpgt_epi16(__m128i a,__m128i b)3194*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmpgt_epi16(__m128i a, __m128i b)
3195*35ffd701SAndroid Build Coastguard Worker {
3196*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(
3197*35ffd701SAndroid Build Coastguard Worker vcgtq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
3198*35ffd701SAndroid Build Coastguard Worker }
3199*35ffd701SAndroid Build Coastguard Worker
3200*35ffd701SAndroid Build Coastguard Worker // Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers
3201*35ffd701SAndroid Build Coastguard Worker // in b for greater than.
3202*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx
_mm_cmpgt_epi32(__m128i a,__m128i b)3203*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b)
3204*35ffd701SAndroid Build Coastguard Worker {
3205*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u32(
3206*35ffd701SAndroid Build Coastguard Worker vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
3207*35ffd701SAndroid Build Coastguard Worker }
3208*35ffd701SAndroid Build Coastguard Worker
3209*35ffd701SAndroid Build Coastguard Worker // Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers
3210*35ffd701SAndroid Build Coastguard Worker // in b for greater than.
3211*35ffd701SAndroid Build Coastguard Worker //
3212*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 > b0) ? 0xff : 0x0
3213*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 > b1) ? 0xff : 0x0
3214*35ffd701SAndroid Build Coastguard Worker // ...
3215*35ffd701SAndroid Build Coastguard Worker // r15 := (a15 > b15) ? 0xff : 0x0
3216*35ffd701SAndroid Build Coastguard Worker //
3217*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/zh-tw/library/wf45zt2b(v=vs.100).aspx
_mm_cmpgt_epi8(__m128i a,__m128i b)3218*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b)
3219*35ffd701SAndroid Build Coastguard Worker {
3220*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
3221*35ffd701SAndroid Build Coastguard Worker vcgtq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
3222*35ffd701SAndroid Build Coastguard Worker }
3223*35ffd701SAndroid Build Coastguard Worker
3224*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3225*35ffd701SAndroid Build Coastguard Worker // for greater-than, and store the results in dst.
3226*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_pd
_mm_cmpgt_pd(__m128d a,__m128d b)3227*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpgt_pd(__m128d a, __m128d b)
3228*35ffd701SAndroid Build Coastguard Worker {
3229*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3230*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(
3231*35ffd701SAndroid Build Coastguard Worker vcgtq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
3232*35ffd701SAndroid Build Coastguard Worker #else
3233*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3234*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3235*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3236*35ffd701SAndroid Build Coastguard Worker uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
3237*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3238*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
3239*35ffd701SAndroid Build Coastguard Worker d[1] = (*(double *) &a1) > (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0);
3240*35ffd701SAndroid Build Coastguard Worker
3241*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3242*35ffd701SAndroid Build Coastguard Worker #endif
3243*35ffd701SAndroid Build Coastguard Worker }
3244*35ffd701SAndroid Build Coastguard Worker
3245*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3246*35ffd701SAndroid Build Coastguard Worker // b for greater-than, store the result in the lower element of dst, and copy
3247*35ffd701SAndroid Build Coastguard Worker // the upper element from a to the upper element of dst.
3248*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_sd
_mm_cmpgt_sd(__m128d a,__m128d b)3249*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpgt_sd(__m128d a, __m128d b)
3250*35ffd701SAndroid Build Coastguard Worker {
3251*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3252*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_cmpgt_pd(a, b));
3253*35ffd701SAndroid Build Coastguard Worker #else
3254*35ffd701SAndroid Build Coastguard Worker // expand "_mm_cmpge_pd()" to reduce unnecessary operations
3255*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3256*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3257*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3258*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3259*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
3260*35ffd701SAndroid Build Coastguard Worker d[1] = a1;
3261*35ffd701SAndroid Build Coastguard Worker
3262*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3263*35ffd701SAndroid Build Coastguard Worker #endif
3264*35ffd701SAndroid Build Coastguard Worker }
3265*35ffd701SAndroid Build Coastguard Worker
3266*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3267*35ffd701SAndroid Build Coastguard Worker // for less-than-or-equal, and store the results in dst.
3268*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_pd
_mm_cmple_pd(__m128d a,__m128d b)3269*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmple_pd(__m128d a, __m128d b)
3270*35ffd701SAndroid Build Coastguard Worker {
3271*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3272*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(
3273*35ffd701SAndroid Build Coastguard Worker vcleq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
3274*35ffd701SAndroid Build Coastguard Worker #else
3275*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3276*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3277*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3278*35ffd701SAndroid Build Coastguard Worker uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
3279*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3280*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
3281*35ffd701SAndroid Build Coastguard Worker d[1] = (*(double *) &a1) <= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0);
3282*35ffd701SAndroid Build Coastguard Worker
3283*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3284*35ffd701SAndroid Build Coastguard Worker #endif
3285*35ffd701SAndroid Build Coastguard Worker }
3286*35ffd701SAndroid Build Coastguard Worker
3287*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3288*35ffd701SAndroid Build Coastguard Worker // b for less-than-or-equal, store the result in the lower element of dst, and
3289*35ffd701SAndroid Build Coastguard Worker // copy the upper element from a to the upper element of dst.
3290*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_sd
_mm_cmple_sd(__m128d a,__m128d b)3291*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmple_sd(__m128d a, __m128d b)
3292*35ffd701SAndroid Build Coastguard Worker {
3293*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3294*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_cmple_pd(a, b));
3295*35ffd701SAndroid Build Coastguard Worker #else
3296*35ffd701SAndroid Build Coastguard Worker // expand "_mm_cmpge_pd()" to reduce unnecessary operations
3297*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3298*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3299*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3300*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3301*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
3302*35ffd701SAndroid Build Coastguard Worker d[1] = a1;
3303*35ffd701SAndroid Build Coastguard Worker
3304*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3305*35ffd701SAndroid Build Coastguard Worker #endif
3306*35ffd701SAndroid Build Coastguard Worker }
3307*35ffd701SAndroid Build Coastguard Worker
3308*35ffd701SAndroid Build Coastguard Worker // Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers
3309*35ffd701SAndroid Build Coastguard Worker // in b for less than.
3310*35ffd701SAndroid Build Coastguard Worker //
3311*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 < b0) ? 0xffff : 0x0
3312*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 < b1) ? 0xffff : 0x0
3313*35ffd701SAndroid Build Coastguard Worker // ...
3314*35ffd701SAndroid Build Coastguard Worker // r7 := (a7 < b7) ? 0xffff : 0x0
3315*35ffd701SAndroid Build Coastguard Worker //
3316*35ffd701SAndroid Build Coastguard Worker // https://technet.microsoft.com/en-us/library/t863edb2(v=vs.100).aspx
_mm_cmplt_epi16(__m128i a,__m128i b)3317*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmplt_epi16(__m128i a, __m128i b)
3318*35ffd701SAndroid Build Coastguard Worker {
3319*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(
3320*35ffd701SAndroid Build Coastguard Worker vcltq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
3321*35ffd701SAndroid Build Coastguard Worker }
3322*35ffd701SAndroid Build Coastguard Worker
3323*35ffd701SAndroid Build Coastguard Worker
3324*35ffd701SAndroid Build Coastguard Worker // Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers
3325*35ffd701SAndroid Build Coastguard Worker // in b for less than.
3326*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/4ak0bf5d(v=vs.100).aspx
_mm_cmplt_epi32(__m128i a,__m128i b)3327*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmplt_epi32(__m128i a, __m128i b)
3328*35ffd701SAndroid Build Coastguard Worker {
3329*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u32(
3330*35ffd701SAndroid Build Coastguard Worker vcltq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
3331*35ffd701SAndroid Build Coastguard Worker }
3332*35ffd701SAndroid Build Coastguard Worker
3333*35ffd701SAndroid Build Coastguard Worker // Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers
3334*35ffd701SAndroid Build Coastguard Worker // in b for lesser than.
3335*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/windows/desktop/9s46csht(v=vs.90).aspx
_mm_cmplt_epi8(__m128i a,__m128i b)3336*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmplt_epi8(__m128i a, __m128i b)
3337*35ffd701SAndroid Build Coastguard Worker {
3338*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
3339*35ffd701SAndroid Build Coastguard Worker vcltq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
3340*35ffd701SAndroid Build Coastguard Worker }
3341*35ffd701SAndroid Build Coastguard Worker
3342*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3343*35ffd701SAndroid Build Coastguard Worker // for less-than, and store the results in dst.
3344*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmplt_pd
_mm_cmplt_pd(__m128d a,__m128d b)3345*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmplt_pd(__m128d a, __m128d b)
3346*35ffd701SAndroid Build Coastguard Worker {
3347*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3348*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(
3349*35ffd701SAndroid Build Coastguard Worker vcltq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
3350*35ffd701SAndroid Build Coastguard Worker #else
3351*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3352*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3353*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3354*35ffd701SAndroid Build Coastguard Worker uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
3355*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3356*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) < (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
3357*35ffd701SAndroid Build Coastguard Worker d[1] = (*(double *) &a1) < (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0);
3358*35ffd701SAndroid Build Coastguard Worker
3359*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3360*35ffd701SAndroid Build Coastguard Worker #endif
3361*35ffd701SAndroid Build Coastguard Worker }
3362*35ffd701SAndroid Build Coastguard Worker
3363*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3364*35ffd701SAndroid Build Coastguard Worker // b for less-than, store the result in the lower element of dst, and copy the
3365*35ffd701SAndroid Build Coastguard Worker // upper element from a to the upper element of dst.
3366*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmplt_sd
_mm_cmplt_sd(__m128d a,__m128d b)3367*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmplt_sd(__m128d a, __m128d b)
3368*35ffd701SAndroid Build Coastguard Worker {
3369*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3370*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_cmplt_pd(a, b));
3371*35ffd701SAndroid Build Coastguard Worker #else
3372*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3373*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3374*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3375*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3376*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) < (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0);
3377*35ffd701SAndroid Build Coastguard Worker d[1] = a1;
3378*35ffd701SAndroid Build Coastguard Worker
3379*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3380*35ffd701SAndroid Build Coastguard Worker #endif
3381*35ffd701SAndroid Build Coastguard Worker }
3382*35ffd701SAndroid Build Coastguard Worker
3383*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3384*35ffd701SAndroid Build Coastguard Worker // for not-equal, and store the results in dst.
3385*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_pd
_mm_cmpneq_pd(__m128d a,__m128d b)3386*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpneq_pd(__m128d a, __m128d b)
3387*35ffd701SAndroid Build Coastguard Worker {
3388*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3389*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s32(vmvnq_s32(vreinterpretq_s32_u64(
3390*35ffd701SAndroid Build Coastguard Worker vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)))));
3391*35ffd701SAndroid Build Coastguard Worker #else
3392*35ffd701SAndroid Build Coastguard Worker // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi)
3393*35ffd701SAndroid Build Coastguard Worker uint32x4_t cmp =
3394*35ffd701SAndroid Build Coastguard Worker vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b));
3395*35ffd701SAndroid Build Coastguard Worker uint32x4_t swapped = vrev64q_u32(cmp);
3396*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u32(vmvnq_u32(vandq_u32(cmp, swapped)));
3397*35ffd701SAndroid Build Coastguard Worker #endif
3398*35ffd701SAndroid Build Coastguard Worker }
3399*35ffd701SAndroid Build Coastguard Worker
3400*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3401*35ffd701SAndroid Build Coastguard Worker // b for not-equal, store the result in the lower element of dst, and copy the
3402*35ffd701SAndroid Build Coastguard Worker // upper element from a to the upper element of dst.
3403*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_sd
_mm_cmpneq_sd(__m128d a,__m128d b)3404*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpneq_sd(__m128d a, __m128d b)
3405*35ffd701SAndroid Build Coastguard Worker {
3406*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_cmpneq_pd(a, b));
3407*35ffd701SAndroid Build Coastguard Worker }
3408*35ffd701SAndroid Build Coastguard Worker
3409*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3410*35ffd701SAndroid Build Coastguard Worker // for not-greater-than-or-equal, and store the results in dst.
3411*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_pd
3412*35ffd701SAndroid Build Coastguard Worker #define _mm_cmpnge_pd(a, b) _mm_cmplt_pd(a, b)
3413*35ffd701SAndroid Build Coastguard Worker
3414*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3415*35ffd701SAndroid Build Coastguard Worker // b for not-greater-than-or-equal, store the result in the lower element of
3416*35ffd701SAndroid Build Coastguard Worker // dst, and copy the upper element from a to the upper element of dst.
3417*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_sd
3418*35ffd701SAndroid Build Coastguard Worker #define _mm_cmpnge_sd(a, b) _mm_cmplt_sd(a, b)
3419*35ffd701SAndroid Build Coastguard Worker
3420*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3421*35ffd701SAndroid Build Coastguard Worker // for not-greater-than, and store the results in dst.
3422*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_cmpngt_pd
3423*35ffd701SAndroid Build Coastguard Worker #define _mm_cmpngt_pd(a, b) _mm_cmple_pd(a, b)
3424*35ffd701SAndroid Build Coastguard Worker
3425*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3426*35ffd701SAndroid Build Coastguard Worker // b for not-greater-than, store the result in the lower element of dst, and
3427*35ffd701SAndroid Build Coastguard Worker // copy the upper element from a to the upper element of dst.
3428*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpngt_sd
3429*35ffd701SAndroid Build Coastguard Worker #define _mm_cmpngt_sd(a, b) _mm_cmple_sd(a, b)
3430*35ffd701SAndroid Build Coastguard Worker
3431*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3432*35ffd701SAndroid Build Coastguard Worker // for not-less-than-or-equal, and store the results in dst.
3433*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnle_pd
3434*35ffd701SAndroid Build Coastguard Worker #define _mm_cmpnle_pd(a, b) _mm_cmpgt_pd(a, b)
3435*35ffd701SAndroid Build Coastguard Worker
3436*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3437*35ffd701SAndroid Build Coastguard Worker // b for not-less-than-or-equal, store the result in the lower element of dst,
3438*35ffd701SAndroid Build Coastguard Worker // and copy the upper element from a to the upper element of dst.
3439*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnle_sd
3440*35ffd701SAndroid Build Coastguard Worker #define _mm_cmpnle_sd(a, b) _mm_cmpgt_sd(a, b)
3441*35ffd701SAndroid Build Coastguard Worker
3442*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3443*35ffd701SAndroid Build Coastguard Worker // for not-less-than, and store the results in dst.
3444*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnlt_pd
3445*35ffd701SAndroid Build Coastguard Worker #define _mm_cmpnlt_pd(a, b) _mm_cmpge_pd(a, b)
3446*35ffd701SAndroid Build Coastguard Worker
3447*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3448*35ffd701SAndroid Build Coastguard Worker // b for not-less-than, store the result in the lower element of dst, and copy
3449*35ffd701SAndroid Build Coastguard Worker // the upper element from a to the upper element of dst.
3450*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnlt_sd
3451*35ffd701SAndroid Build Coastguard Worker #define _mm_cmpnlt_sd(a, b) _mm_cmpge_sd(a, b)
3452*35ffd701SAndroid Build Coastguard Worker
3453*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3454*35ffd701SAndroid Build Coastguard Worker // to see if neither is NaN, and store the results in dst.
3455*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpord_pd
_mm_cmpord_pd(__m128d a,__m128d b)3456*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpord_pd(__m128d a, __m128d b)
3457*35ffd701SAndroid Build Coastguard Worker {
3458*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3459*35ffd701SAndroid Build Coastguard Worker // Excluding NaNs, any two floating point numbers can be compared.
3460*35ffd701SAndroid Build Coastguard Worker uint64x2_t not_nan_a =
3461*35ffd701SAndroid Build Coastguard Worker vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(a));
3462*35ffd701SAndroid Build Coastguard Worker uint64x2_t not_nan_b =
3463*35ffd701SAndroid Build Coastguard Worker vceqq_f64(vreinterpretq_f64_m128d(b), vreinterpretq_f64_m128d(b));
3464*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vandq_u64(not_nan_a, not_nan_b));
3465*35ffd701SAndroid Build Coastguard Worker #else
3466*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3467*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3468*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3469*35ffd701SAndroid Build Coastguard Worker uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
3470*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3471*35ffd701SAndroid Build Coastguard Worker d[0] = ((*(double *) &a0) == (*(double *) &a0) &&
3472*35ffd701SAndroid Build Coastguard Worker (*(double *) &b0) == (*(double *) &b0))
3473*35ffd701SAndroid Build Coastguard Worker ? ~UINT64_C(0)
3474*35ffd701SAndroid Build Coastguard Worker : UINT64_C(0);
3475*35ffd701SAndroid Build Coastguard Worker d[1] = ((*(double *) &a1) == (*(double *) &a1) &&
3476*35ffd701SAndroid Build Coastguard Worker (*(double *) &b1) == (*(double *) &b1))
3477*35ffd701SAndroid Build Coastguard Worker ? ~UINT64_C(0)
3478*35ffd701SAndroid Build Coastguard Worker : UINT64_C(0);
3479*35ffd701SAndroid Build Coastguard Worker
3480*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3481*35ffd701SAndroid Build Coastguard Worker #endif
3482*35ffd701SAndroid Build Coastguard Worker }
3483*35ffd701SAndroid Build Coastguard Worker
3484*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3485*35ffd701SAndroid Build Coastguard Worker // b to see if neither is NaN, store the result in the lower element of dst, and
3486*35ffd701SAndroid Build Coastguard Worker // copy the upper element from a to the upper element of dst.
3487*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpord_sd
_mm_cmpord_sd(__m128d a,__m128d b)3488*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpord_sd(__m128d a, __m128d b)
3489*35ffd701SAndroid Build Coastguard Worker {
3490*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3491*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_cmpord_pd(a, b));
3492*35ffd701SAndroid Build Coastguard Worker #else
3493*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3494*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3495*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3496*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3497*35ffd701SAndroid Build Coastguard Worker d[0] = ((*(double *) &a0) == (*(double *) &a0) &&
3498*35ffd701SAndroid Build Coastguard Worker (*(double *) &b0) == (*(double *) &b0))
3499*35ffd701SAndroid Build Coastguard Worker ? ~UINT64_C(0)
3500*35ffd701SAndroid Build Coastguard Worker : UINT64_C(0);
3501*35ffd701SAndroid Build Coastguard Worker d[1] = a1;
3502*35ffd701SAndroid Build Coastguard Worker
3503*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3504*35ffd701SAndroid Build Coastguard Worker #endif
3505*35ffd701SAndroid Build Coastguard Worker }
3506*35ffd701SAndroid Build Coastguard Worker
3507*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b
3508*35ffd701SAndroid Build Coastguard Worker // to see if either is NaN, and store the results in dst.
3509*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpunord_pd
_mm_cmpunord_pd(__m128d a,__m128d b)3510*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpunord_pd(__m128d a, __m128d b)
3511*35ffd701SAndroid Build Coastguard Worker {
3512*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3513*35ffd701SAndroid Build Coastguard Worker // Two NaNs are not equal in comparison operation.
3514*35ffd701SAndroid Build Coastguard Worker uint64x2_t not_nan_a =
3515*35ffd701SAndroid Build Coastguard Worker vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(a));
3516*35ffd701SAndroid Build Coastguard Worker uint64x2_t not_nan_b =
3517*35ffd701SAndroid Build Coastguard Worker vceqq_f64(vreinterpretq_f64_m128d(b), vreinterpretq_f64_m128d(b));
3518*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s32(
3519*35ffd701SAndroid Build Coastguard Worker vmvnq_s32(vreinterpretq_s32_u64(vandq_u64(not_nan_a, not_nan_b))));
3520*35ffd701SAndroid Build Coastguard Worker #else
3521*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3522*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3523*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3524*35ffd701SAndroid Build Coastguard Worker uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
3525*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3526*35ffd701SAndroid Build Coastguard Worker d[0] = ((*(double *) &a0) == (*(double *) &a0) &&
3527*35ffd701SAndroid Build Coastguard Worker (*(double *) &b0) == (*(double *) &b0))
3528*35ffd701SAndroid Build Coastguard Worker ? UINT64_C(0)
3529*35ffd701SAndroid Build Coastguard Worker : ~UINT64_C(0);
3530*35ffd701SAndroid Build Coastguard Worker d[1] = ((*(double *) &a1) == (*(double *) &a1) &&
3531*35ffd701SAndroid Build Coastguard Worker (*(double *) &b1) == (*(double *) &b1))
3532*35ffd701SAndroid Build Coastguard Worker ? UINT64_C(0)
3533*35ffd701SAndroid Build Coastguard Worker : ~UINT64_C(0);
3534*35ffd701SAndroid Build Coastguard Worker
3535*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3536*35ffd701SAndroid Build Coastguard Worker #endif
3537*35ffd701SAndroid Build Coastguard Worker }
3538*35ffd701SAndroid Build Coastguard Worker
3539*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
3540*35ffd701SAndroid Build Coastguard Worker // b to see if either is NaN, store the result in the lower element of dst, and
3541*35ffd701SAndroid Build Coastguard Worker // copy the upper element from a to the upper element of dst.
3542*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpunord_sd
_mm_cmpunord_sd(__m128d a,__m128d b)3543*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cmpunord_sd(__m128d a, __m128d b)
3544*35ffd701SAndroid Build Coastguard Worker {
3545*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3546*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_cmpunord_pd(a, b));
3547*35ffd701SAndroid Build Coastguard Worker #else
3548*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3549*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3550*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
3551*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
3552*35ffd701SAndroid Build Coastguard Worker d[0] = ((*(double *) &a0) == (*(double *) &a0) &&
3553*35ffd701SAndroid Build Coastguard Worker (*(double *) &b0) == (*(double *) &b0))
3554*35ffd701SAndroid Build Coastguard Worker ? UINT64_C(0)
3555*35ffd701SAndroid Build Coastguard Worker : ~UINT64_C(0);
3556*35ffd701SAndroid Build Coastguard Worker d[1] = a1;
3557*35ffd701SAndroid Build Coastguard Worker
3558*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
3559*35ffd701SAndroid Build Coastguard Worker #endif
3560*35ffd701SAndroid Build Coastguard Worker }
3561*35ffd701SAndroid Build Coastguard Worker
3562*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point element in a and b
3563*35ffd701SAndroid Build Coastguard Worker // for greater-than-or-equal, and return the boolean result (0 or 1).
3564*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comige_sd
_mm_comige_sd(__m128d a,__m128d b)3565*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comige_sd(__m128d a, __m128d b)
3566*35ffd701SAndroid Build Coastguard Worker {
3567*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3568*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u64(vcgeq_f64(a, b), 0) & 0x1;
3569*35ffd701SAndroid Build Coastguard Worker #else
3570*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3571*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3572*35ffd701SAndroid Build Coastguard Worker
3573*35ffd701SAndroid Build Coastguard Worker return (*(double *) &a0 >= *(double *) &b0);
3574*35ffd701SAndroid Build Coastguard Worker #endif
3575*35ffd701SAndroid Build Coastguard Worker }
3576*35ffd701SAndroid Build Coastguard Worker
3577*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point element in a and b
3578*35ffd701SAndroid Build Coastguard Worker // for greater-than, and return the boolean result (0 or 1).
3579*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comigt_sd
_mm_comigt_sd(__m128d a,__m128d b)3580*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comigt_sd(__m128d a, __m128d b)
3581*35ffd701SAndroid Build Coastguard Worker {
3582*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3583*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u64(vcgtq_f64(a, b), 0) & 0x1;
3584*35ffd701SAndroid Build Coastguard Worker #else
3585*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3586*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3587*35ffd701SAndroid Build Coastguard Worker
3588*35ffd701SAndroid Build Coastguard Worker return (*(double *) &a0 > *(double *) &b0);
3589*35ffd701SAndroid Build Coastguard Worker #endif
3590*35ffd701SAndroid Build Coastguard Worker }
3591*35ffd701SAndroid Build Coastguard Worker
3592*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point element in a and b
3593*35ffd701SAndroid Build Coastguard Worker // for less-than-or-equal, and return the boolean result (0 or 1).
3594*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comile_sd
_mm_comile_sd(__m128d a,__m128d b)3595*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comile_sd(__m128d a, __m128d b)
3596*35ffd701SAndroid Build Coastguard Worker {
3597*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3598*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u64(vcleq_f64(a, b), 0) & 0x1;
3599*35ffd701SAndroid Build Coastguard Worker #else
3600*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3601*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3602*35ffd701SAndroid Build Coastguard Worker
3603*35ffd701SAndroid Build Coastguard Worker return (*(double *) &a0 <= *(double *) &b0);
3604*35ffd701SAndroid Build Coastguard Worker #endif
3605*35ffd701SAndroid Build Coastguard Worker }
3606*35ffd701SAndroid Build Coastguard Worker
3607*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point element in a and b
3608*35ffd701SAndroid Build Coastguard Worker // for less-than, and return the boolean result (0 or 1).
3609*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comilt_sd
_mm_comilt_sd(__m128d a,__m128d b)3610*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comilt_sd(__m128d a, __m128d b)
3611*35ffd701SAndroid Build Coastguard Worker {
3612*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3613*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u64(vcltq_f64(a, b), 0) & 0x1;
3614*35ffd701SAndroid Build Coastguard Worker #else
3615*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
3616*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
3617*35ffd701SAndroid Build Coastguard Worker
3618*35ffd701SAndroid Build Coastguard Worker return (*(double *) &a0 < *(double *) &b0);
3619*35ffd701SAndroid Build Coastguard Worker #endif
3620*35ffd701SAndroid Build Coastguard Worker }
3621*35ffd701SAndroid Build Coastguard Worker
3622*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point element in a and b
3623*35ffd701SAndroid Build Coastguard Worker // for equality, and return the boolean result (0 or 1).
3624*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comieq_sd
_mm_comieq_sd(__m128d a,__m128d b)3625*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comieq_sd(__m128d a, __m128d b)
3626*35ffd701SAndroid Build Coastguard Worker {
3627*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3628*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u64(vceqq_f64(a, b), 0) & 0x1;
3629*35ffd701SAndroid Build Coastguard Worker #else
3630*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_not_nan =
3631*35ffd701SAndroid Build Coastguard Worker vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(a));
3632*35ffd701SAndroid Build Coastguard Worker uint32x4_t b_not_nan =
3633*35ffd701SAndroid Build Coastguard Worker vceqq_u32(vreinterpretq_u32_m128d(b), vreinterpretq_u32_m128d(b));
3634*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan);
3635*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_eq_b =
3636*35ffd701SAndroid Build Coastguard Worker vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b));
3637*35ffd701SAndroid Build Coastguard Worker uint64x2_t and_results = vandq_u64(vreinterpretq_u64_u32(a_and_b_not_nan),
3638*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u64_u32(a_eq_b));
3639*35ffd701SAndroid Build Coastguard Worker return !!vgetq_lane_u64(and_results, 0);
3640*35ffd701SAndroid Build Coastguard Worker #endif
3641*35ffd701SAndroid Build Coastguard Worker }
3642*35ffd701SAndroid Build Coastguard Worker
3643*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point element in a and b
3644*35ffd701SAndroid Build Coastguard Worker // for not-equal, and return the boolean result (0 or 1).
3645*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comineq_sd
_mm_comineq_sd(__m128d a,__m128d b)3646*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_comineq_sd(__m128d a, __m128d b)
3647*35ffd701SAndroid Build Coastguard Worker {
3648*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3649*35ffd701SAndroid Build Coastguard Worker return !vgetq_lane_u64(vceqq_f64(a, b), 0);
3650*35ffd701SAndroid Build Coastguard Worker #else
3651*35ffd701SAndroid Build Coastguard Worker // FIXME we should handle NaN condition here
3652*35ffd701SAndroid Build Coastguard Worker uint32x4_t a_eq_b =
3653*35ffd701SAndroid Build Coastguard Worker vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b));
3654*35ffd701SAndroid Build Coastguard Worker return !vgetq_lane_u64(vreinterpretq_u64_u32(a_eq_b), 0);
3655*35ffd701SAndroid Build Coastguard Worker #endif
3656*35ffd701SAndroid Build Coastguard Worker }
3657*35ffd701SAndroid Build Coastguard Worker
3658*35ffd701SAndroid Build Coastguard Worker // Convert packed signed 32-bit integers in a to packed double-precision
3659*35ffd701SAndroid Build Coastguard Worker // (64-bit) floating-point elements, and store the results in dst.
3660*35ffd701SAndroid Build Coastguard Worker //
3661*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
3662*35ffd701SAndroid Build Coastguard Worker // i := j*32
3663*35ffd701SAndroid Build Coastguard Worker // m := j*64
3664*35ffd701SAndroid Build Coastguard Worker // dst[m+63:m] := Convert_Int32_To_FP64(a[i+31:i])
3665*35ffd701SAndroid Build Coastguard Worker // ENDFOR
3666*35ffd701SAndroid Build Coastguard Worker //
3667*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtepi32_pd
_mm_cvtepi32_pd(__m128i a)3668*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cvtepi32_pd(__m128i a)
3669*35ffd701SAndroid Build Coastguard Worker {
3670*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3671*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
3672*35ffd701SAndroid Build Coastguard Worker vcvtq_f64_s64(vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a)))));
3673*35ffd701SAndroid Build Coastguard Worker #else
3674*35ffd701SAndroid Build Coastguard Worker double a0 = (double) vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0);
3675*35ffd701SAndroid Build Coastguard Worker double a1 = (double) vgetq_lane_s32(vreinterpretq_s32_m128i(a), 1);
3676*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(a1, a0);
3677*35ffd701SAndroid Build Coastguard Worker #endif
3678*35ffd701SAndroid Build Coastguard Worker }
3679*35ffd701SAndroid Build Coastguard Worker
3680*35ffd701SAndroid Build Coastguard Worker // Converts the four signed 32-bit integer values of a to single-precision,
3681*35ffd701SAndroid Build Coastguard Worker // floating-point values
3682*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/36bwxcx5(v=vs.100).aspx
_mm_cvtepi32_ps(__m128i a)3683*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtepi32_ps(__m128i a)
3684*35ffd701SAndroid Build Coastguard Worker {
3685*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcvtq_f32_s32(vreinterpretq_s32_m128i(a)));
3686*35ffd701SAndroid Build Coastguard Worker }
3687*35ffd701SAndroid Build Coastguard Worker
3688*35ffd701SAndroid Build Coastguard Worker // Convert packed double-precision (64-bit) floating-point elements in a to
3689*35ffd701SAndroid Build Coastguard Worker // packed 32-bit integers, and store the results in dst.
3690*35ffd701SAndroid Build Coastguard Worker //
3691*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
3692*35ffd701SAndroid Build Coastguard Worker // i := 32*j
3693*35ffd701SAndroid Build Coastguard Worker // k := 64*j
3694*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := Convert_FP64_To_Int32(a[k+63:k])
3695*35ffd701SAndroid Build Coastguard Worker // ENDFOR
3696*35ffd701SAndroid Build Coastguard Worker //
3697*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_epi32
_mm_cvtpd_epi32(__m128d a)3698*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtpd_epi32(__m128d a)
3699*35ffd701SAndroid Build Coastguard Worker {
3700*35ffd701SAndroid Build Coastguard Worker __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION);
3701*35ffd701SAndroid Build Coastguard Worker double d0 = ((double *) &rnd)[0];
3702*35ffd701SAndroid Build Coastguard Worker double d1 = ((double *) &rnd)[1];
3703*35ffd701SAndroid Build Coastguard Worker return _mm_set_epi32(0, 0, (int32_t) d1, (int32_t) d0);
3704*35ffd701SAndroid Build Coastguard Worker }
3705*35ffd701SAndroid Build Coastguard Worker
3706*35ffd701SAndroid Build Coastguard Worker // Convert packed double-precision (64-bit) floating-point elements in a to
3707*35ffd701SAndroid Build Coastguard Worker // packed 32-bit integers, and store the results in dst.
3708*35ffd701SAndroid Build Coastguard Worker //
3709*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
3710*35ffd701SAndroid Build Coastguard Worker // i := 32*j
3711*35ffd701SAndroid Build Coastguard Worker // k := 64*j
3712*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := Convert_FP64_To_Int32(a[k+63:k])
3713*35ffd701SAndroid Build Coastguard Worker // ENDFOR
3714*35ffd701SAndroid Build Coastguard Worker //
3715*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_pi32
_mm_cvtpd_pi32(__m128d a)3716*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_cvtpd_pi32(__m128d a)
3717*35ffd701SAndroid Build Coastguard Worker {
3718*35ffd701SAndroid Build Coastguard Worker __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION);
3719*35ffd701SAndroid Build Coastguard Worker double d0 = ((double *) &rnd)[0];
3720*35ffd701SAndroid Build Coastguard Worker double d1 = ((double *) &rnd)[1];
3721*35ffd701SAndroid Build Coastguard Worker int32_t ALIGN_STRUCT(16) data[2] = {(int32_t) d0, (int32_t) d1};
3722*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(vld1_s32(data));
3723*35ffd701SAndroid Build Coastguard Worker }
3724*35ffd701SAndroid Build Coastguard Worker
3725*35ffd701SAndroid Build Coastguard Worker // Convert packed double-precision (64-bit) floating-point elements in a to
3726*35ffd701SAndroid Build Coastguard Worker // packed single-precision (32-bit) floating-point elements, and store the
3727*35ffd701SAndroid Build Coastguard Worker // results in dst.
3728*35ffd701SAndroid Build Coastguard Worker //
3729*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
3730*35ffd701SAndroid Build Coastguard Worker // i := 32*j
3731*35ffd701SAndroid Build Coastguard Worker // k := 64*j
3732*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := Convert_FP64_To_FP32(a[k+64:k])
3733*35ffd701SAndroid Build Coastguard Worker // ENDFOR
3734*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := 0
3735*35ffd701SAndroid Build Coastguard Worker //
3736*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_ps
_mm_cvtpd_ps(__m128d a)3737*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtpd_ps(__m128d a)
3738*35ffd701SAndroid Build Coastguard Worker {
3739*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3740*35ffd701SAndroid Build Coastguard Worker float32x2_t tmp = vcvt_f32_f64(vreinterpretq_f64_m128d(a));
3741*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vcombine_f32(tmp, vdup_n_f32(0)));
3742*35ffd701SAndroid Build Coastguard Worker #else
3743*35ffd701SAndroid Build Coastguard Worker float a0 = (float) ((double *) &a)[0];
3744*35ffd701SAndroid Build Coastguard Worker float a1 = (float) ((double *) &a)[1];
3745*35ffd701SAndroid Build Coastguard Worker return _mm_set_ps(0, 0, a1, a0);
3746*35ffd701SAndroid Build Coastguard Worker #endif
3747*35ffd701SAndroid Build Coastguard Worker }
3748*35ffd701SAndroid Build Coastguard Worker
3749*35ffd701SAndroid Build Coastguard Worker // Convert packed signed 32-bit integers in a to packed double-precision
3750*35ffd701SAndroid Build Coastguard Worker // (64-bit) floating-point elements, and store the results in dst.
3751*35ffd701SAndroid Build Coastguard Worker //
3752*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
3753*35ffd701SAndroid Build Coastguard Worker // i := j*32
3754*35ffd701SAndroid Build Coastguard Worker // m := j*64
3755*35ffd701SAndroid Build Coastguard Worker // dst[m+63:m] := Convert_Int32_To_FP64(a[i+31:i])
3756*35ffd701SAndroid Build Coastguard Worker // ENDFOR
3757*35ffd701SAndroid Build Coastguard Worker //
3758*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_pd
_mm_cvtpi32_pd(__m64 a)3759*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cvtpi32_pd(__m64 a)
3760*35ffd701SAndroid Build Coastguard Worker {
3761*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3762*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
3763*35ffd701SAndroid Build Coastguard Worker vcvtq_f64_s64(vmovl_s32(vreinterpret_s32_m64(a))));
3764*35ffd701SAndroid Build Coastguard Worker #else
3765*35ffd701SAndroid Build Coastguard Worker double a0 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 0);
3766*35ffd701SAndroid Build Coastguard Worker double a1 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 1);
3767*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(a1, a0);
3768*35ffd701SAndroid Build Coastguard Worker #endif
3769*35ffd701SAndroid Build Coastguard Worker }
3770*35ffd701SAndroid Build Coastguard Worker
3771*35ffd701SAndroid Build Coastguard Worker // Converts the four single-precision, floating-point values of a to signed
3772*35ffd701SAndroid Build Coastguard Worker // 32-bit integer values.
3773*35ffd701SAndroid Build Coastguard Worker //
3774*35ffd701SAndroid Build Coastguard Worker // r0 := (int) a0
3775*35ffd701SAndroid Build Coastguard Worker // r1 := (int) a1
3776*35ffd701SAndroid Build Coastguard Worker // r2 := (int) a2
3777*35ffd701SAndroid Build Coastguard Worker // r3 := (int) a3
3778*35ffd701SAndroid Build Coastguard Worker //
3779*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/xdc42k5e(v=vs.100).aspx
3780*35ffd701SAndroid Build Coastguard Worker // *NOTE*. The default rounding mode on SSE is 'round to even', which ARMv7-A
3781*35ffd701SAndroid Build Coastguard Worker // does not support! It is supported on ARMv8-A however.
_mm_cvtps_epi32(__m128 a)3782*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a)
3783*35ffd701SAndroid Build Coastguard Worker {
3784*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3785*35ffd701SAndroid Build Coastguard Worker switch (_MM_GET_ROUNDING_MODE()) {
3786*35ffd701SAndroid Build Coastguard Worker case _MM_ROUND_NEAREST:
3787*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcvtnq_s32_f32(a));
3788*35ffd701SAndroid Build Coastguard Worker case _MM_ROUND_DOWN:
3789*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcvtmq_s32_f32(a));
3790*35ffd701SAndroid Build Coastguard Worker case _MM_ROUND_UP:
3791*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcvtpq_s32_f32(a));
3792*35ffd701SAndroid Build Coastguard Worker default: // _MM_ROUND_TOWARD_ZERO
3793*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcvtq_s32_f32(a));
3794*35ffd701SAndroid Build Coastguard Worker }
3795*35ffd701SAndroid Build Coastguard Worker #else
3796*35ffd701SAndroid Build Coastguard Worker float *f = (float *) &a;
3797*35ffd701SAndroid Build Coastguard Worker switch (_MM_GET_ROUNDING_MODE()) {
3798*35ffd701SAndroid Build Coastguard Worker case _MM_ROUND_NEAREST: {
3799*35ffd701SAndroid Build Coastguard Worker uint32x4_t signmask = vdupq_n_u32(0x80000000);
3800*35ffd701SAndroid Build Coastguard Worker float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a),
3801*35ffd701SAndroid Build Coastguard Worker vdupq_n_f32(0.5f)); /* +/- 0.5 */
3802*35ffd701SAndroid Build Coastguard Worker int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32(
3803*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/
3804*35ffd701SAndroid Build Coastguard Worker int32x4_t r_trunc = vcvtq_s32_f32(
3805*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */
3806*35ffd701SAndroid Build Coastguard Worker int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32(
3807*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */
3808*35ffd701SAndroid Build Coastguard Worker int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone),
3809*35ffd701SAndroid Build Coastguard Worker vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */
3810*35ffd701SAndroid Build Coastguard Worker float32x4_t delta = vsubq_f32(
3811*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a),
3812*35ffd701SAndroid Build Coastguard Worker vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */
3813*35ffd701SAndroid Build Coastguard Worker uint32x4_t is_delta_half =
3814*35ffd701SAndroid Build Coastguard Worker vceqq_f32(delta, half); /* delta == +/- 0.5 */
3815*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
3816*35ffd701SAndroid Build Coastguard Worker vbslq_s32(is_delta_half, r_even, r_normal));
3817*35ffd701SAndroid Build Coastguard Worker }
3818*35ffd701SAndroid Build Coastguard Worker case _MM_ROUND_DOWN:
3819*35ffd701SAndroid Build Coastguard Worker return _mm_set_epi32(floorf(f[3]), floorf(f[2]), floorf(f[1]),
3820*35ffd701SAndroid Build Coastguard Worker floorf(f[0]));
3821*35ffd701SAndroid Build Coastguard Worker case _MM_ROUND_UP:
3822*35ffd701SAndroid Build Coastguard Worker return _mm_set_epi32(ceilf(f[3]), ceilf(f[2]), ceilf(f[1]),
3823*35ffd701SAndroid Build Coastguard Worker ceilf(f[0]));
3824*35ffd701SAndroid Build Coastguard Worker default: // _MM_ROUND_TOWARD_ZERO
3825*35ffd701SAndroid Build Coastguard Worker return _mm_set_epi32((int32_t) f[3], (int32_t) f[2], (int32_t) f[1],
3826*35ffd701SAndroid Build Coastguard Worker (int32_t) f[0]);
3827*35ffd701SAndroid Build Coastguard Worker }
3828*35ffd701SAndroid Build Coastguard Worker #endif
3829*35ffd701SAndroid Build Coastguard Worker }
3830*35ffd701SAndroid Build Coastguard Worker
3831*35ffd701SAndroid Build Coastguard Worker // Convert packed single-precision (32-bit) floating-point elements in a to
3832*35ffd701SAndroid Build Coastguard Worker // packed double-precision (64-bit) floating-point elements, and store the
3833*35ffd701SAndroid Build Coastguard Worker // results in dst.
3834*35ffd701SAndroid Build Coastguard Worker //
3835*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
3836*35ffd701SAndroid Build Coastguard Worker // i := 64*j
3837*35ffd701SAndroid Build Coastguard Worker // k := 32*j
3838*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := Convert_FP32_To_FP64(a[k+31:k])
3839*35ffd701SAndroid Build Coastguard Worker // ENDFOR
3840*35ffd701SAndroid Build Coastguard Worker //
3841*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pd
_mm_cvtps_pd(__m128 a)3842*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cvtps_pd(__m128 a)
3843*35ffd701SAndroid Build Coastguard Worker {
3844*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3845*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
3846*35ffd701SAndroid Build Coastguard Worker vcvt_f64_f32(vget_low_f32(vreinterpretq_f32_m128(a))));
3847*35ffd701SAndroid Build Coastguard Worker #else
3848*35ffd701SAndroid Build Coastguard Worker double a0 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0);
3849*35ffd701SAndroid Build Coastguard Worker double a1 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 1);
3850*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(a1, a0);
3851*35ffd701SAndroid Build Coastguard Worker #endif
3852*35ffd701SAndroid Build Coastguard Worker }
3853*35ffd701SAndroid Build Coastguard Worker
3854*35ffd701SAndroid Build Coastguard Worker // Copy the lower double-precision (64-bit) floating-point element of a to dst.
3855*35ffd701SAndroid Build Coastguard Worker //
3856*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0]
3857*35ffd701SAndroid Build Coastguard Worker //
3858*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_f64
_mm_cvtsd_f64(__m128d a)3859*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE double _mm_cvtsd_f64(__m128d a)
3860*35ffd701SAndroid Build Coastguard Worker {
3861*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3862*35ffd701SAndroid Build Coastguard Worker return (double) vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0);
3863*35ffd701SAndroid Build Coastguard Worker #else
3864*35ffd701SAndroid Build Coastguard Worker return ((double *) &a)[0];
3865*35ffd701SAndroid Build Coastguard Worker #endif
3866*35ffd701SAndroid Build Coastguard Worker }
3867*35ffd701SAndroid Build Coastguard Worker
3868*35ffd701SAndroid Build Coastguard Worker // Convert the lower double-precision (64-bit) floating-point element in a to a
3869*35ffd701SAndroid Build Coastguard Worker // 32-bit integer, and store the result in dst.
3870*35ffd701SAndroid Build Coastguard Worker //
3871*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := Convert_FP64_To_Int32(a[63:0])
3872*35ffd701SAndroid Build Coastguard Worker //
3873*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_si32
_mm_cvtsd_si32(__m128d a)3874*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int32_t _mm_cvtsd_si32(__m128d a)
3875*35ffd701SAndroid Build Coastguard Worker {
3876*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3877*35ffd701SAndroid Build Coastguard Worker return (int32_t) vgetq_lane_f64(vrndiq_f64(vreinterpretq_f64_m128d(a)), 0);
3878*35ffd701SAndroid Build Coastguard Worker #else
3879*35ffd701SAndroid Build Coastguard Worker __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION);
3880*35ffd701SAndroid Build Coastguard Worker double ret = ((double *) &rnd)[0];
3881*35ffd701SAndroid Build Coastguard Worker return (int32_t) ret;
3882*35ffd701SAndroid Build Coastguard Worker #endif
3883*35ffd701SAndroid Build Coastguard Worker }
3884*35ffd701SAndroid Build Coastguard Worker
3885*35ffd701SAndroid Build Coastguard Worker // Convert the lower double-precision (64-bit) floating-point element in a to a
3886*35ffd701SAndroid Build Coastguard Worker // 64-bit integer, and store the result in dst.
3887*35ffd701SAndroid Build Coastguard Worker //
3888*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := Convert_FP64_To_Int64(a[63:0])
3889*35ffd701SAndroid Build Coastguard Worker //
3890*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_si64
_mm_cvtsd_si64(__m128d a)3891*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int64_t _mm_cvtsd_si64(__m128d a)
3892*35ffd701SAndroid Build Coastguard Worker {
3893*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3894*35ffd701SAndroid Build Coastguard Worker return (int64_t) vgetq_lane_f64(vrndiq_f64(vreinterpretq_f64_m128d(a)), 0);
3895*35ffd701SAndroid Build Coastguard Worker #else
3896*35ffd701SAndroid Build Coastguard Worker __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION);
3897*35ffd701SAndroid Build Coastguard Worker double ret = ((double *) &rnd)[0];
3898*35ffd701SAndroid Build Coastguard Worker return (int64_t) ret;
3899*35ffd701SAndroid Build Coastguard Worker #endif
3900*35ffd701SAndroid Build Coastguard Worker }
3901*35ffd701SAndroid Build Coastguard Worker
3902*35ffd701SAndroid Build Coastguard Worker // Convert the lower double-precision (64-bit) floating-point element in a to a
3903*35ffd701SAndroid Build Coastguard Worker // 64-bit integer, and store the result in dst.
3904*35ffd701SAndroid Build Coastguard Worker //
3905*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := Convert_FP64_To_Int64(a[63:0])
3906*35ffd701SAndroid Build Coastguard Worker //
3907*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_si64x
3908*35ffd701SAndroid Build Coastguard Worker #define _mm_cvtsd_si64x _mm_cvtsd_si64
3909*35ffd701SAndroid Build Coastguard Worker
3910*35ffd701SAndroid Build Coastguard Worker // Convert the lower double-precision (64-bit) floating-point element in b to a
3911*35ffd701SAndroid Build Coastguard Worker // single-precision (32-bit) floating-point element, store the result in the
3912*35ffd701SAndroid Build Coastguard Worker // lower element of dst, and copy the upper 3 packed elements from a to the
3913*35ffd701SAndroid Build Coastguard Worker // upper elements of dst.
3914*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_ss
_mm_cvtsd_ss(__m128 a,__m128d b)3915*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_cvtsd_ss(__m128 a, __m128d b)
3916*35ffd701SAndroid Build Coastguard Worker {
3917*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3918*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vsetq_lane_f32(
3919*35ffd701SAndroid Build Coastguard Worker vget_lane_f32(vcvt_f32_f64(vreinterpretq_f64_m128d(b)), 0),
3920*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a), 0));
3921*35ffd701SAndroid Build Coastguard Worker #else
3922*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vsetq_lane_f32((float) ((double *) &b)[0],
3923*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a), 0));
3924*35ffd701SAndroid Build Coastguard Worker #endif
3925*35ffd701SAndroid Build Coastguard Worker }
3926*35ffd701SAndroid Build Coastguard Worker
3927*35ffd701SAndroid Build Coastguard Worker // Copy the lower 32-bit integer in a to dst.
3928*35ffd701SAndroid Build Coastguard Worker //
3929*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := a[31:0]
3930*35ffd701SAndroid Build Coastguard Worker //
3931*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si32
_mm_cvtsi128_si32(__m128i a)3932*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_cvtsi128_si32(__m128i a)
3933*35ffd701SAndroid Build Coastguard Worker {
3934*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0);
3935*35ffd701SAndroid Build Coastguard Worker }
3936*35ffd701SAndroid Build Coastguard Worker
3937*35ffd701SAndroid Build Coastguard Worker // Copy the lower 64-bit integer in a to dst.
3938*35ffd701SAndroid Build Coastguard Worker //
3939*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0]
3940*35ffd701SAndroid Build Coastguard Worker //
3941*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64
_mm_cvtsi128_si64(__m128i a)3942*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int64_t _mm_cvtsi128_si64(__m128i a)
3943*35ffd701SAndroid Build Coastguard Worker {
3944*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_s64(vreinterpretq_s64_m128i(a), 0);
3945*35ffd701SAndroid Build Coastguard Worker }
3946*35ffd701SAndroid Build Coastguard Worker
3947*35ffd701SAndroid Build Coastguard Worker // Copy the lower 64-bit integer in a to dst.
3948*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x
3949*35ffd701SAndroid Build Coastguard Worker #define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a)
3950*35ffd701SAndroid Build Coastguard Worker
3951*35ffd701SAndroid Build Coastguard Worker // Convert the signed 32-bit integer b to a double-precision (64-bit)
3952*35ffd701SAndroid Build Coastguard Worker // floating-point element, store the result in the lower element of dst, and
3953*35ffd701SAndroid Build Coastguard Worker // copy the upper element from a to the upper element of dst.
3954*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_sd
_mm_cvtsi32_sd(__m128d a,int32_t b)3955*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cvtsi32_sd(__m128d a, int32_t b)
3956*35ffd701SAndroid Build Coastguard Worker {
3957*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3958*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
3959*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f64((double) b, vreinterpretq_f64_m128d(a), 0));
3960*35ffd701SAndroid Build Coastguard Worker #else
3961*35ffd701SAndroid Build Coastguard Worker double bf = (double) b;
3962*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(
3963*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s64(*(int64_t *) &bf, vreinterpretq_s64_m128d(a), 0));
3964*35ffd701SAndroid Build Coastguard Worker #endif
3965*35ffd701SAndroid Build Coastguard Worker }
3966*35ffd701SAndroid Build Coastguard Worker
3967*35ffd701SAndroid Build Coastguard Worker // Copy the lower 64-bit integer in a to dst.
3968*35ffd701SAndroid Build Coastguard Worker //
3969*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0]
3970*35ffd701SAndroid Build Coastguard Worker //
3971*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x
3972*35ffd701SAndroid Build Coastguard Worker #define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a)
3973*35ffd701SAndroid Build Coastguard Worker
3974*35ffd701SAndroid Build Coastguard Worker // Moves 32-bit integer a to the least significant 32 bits of an __m128 object,
3975*35ffd701SAndroid Build Coastguard Worker // zero extending the upper bits.
3976*35ffd701SAndroid Build Coastguard Worker //
3977*35ffd701SAndroid Build Coastguard Worker // r0 := a
3978*35ffd701SAndroid Build Coastguard Worker // r1 := 0x0
3979*35ffd701SAndroid Build Coastguard Worker // r2 := 0x0
3980*35ffd701SAndroid Build Coastguard Worker // r3 := 0x0
3981*35ffd701SAndroid Build Coastguard Worker //
3982*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/ct3539ha%28v=vs.90%29.aspx
_mm_cvtsi32_si128(int a)3983*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtsi32_si128(int a)
3984*35ffd701SAndroid Build Coastguard Worker {
3985*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vsetq_lane_s32(a, vdupq_n_s32(0), 0));
3986*35ffd701SAndroid Build Coastguard Worker }
3987*35ffd701SAndroid Build Coastguard Worker
3988*35ffd701SAndroid Build Coastguard Worker // Convert the signed 64-bit integer b to a double-precision (64-bit)
3989*35ffd701SAndroid Build Coastguard Worker // floating-point element, store the result in the lower element of dst, and
3990*35ffd701SAndroid Build Coastguard Worker // copy the upper element from a to the upper element of dst.
3991*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_sd
_mm_cvtsi64_sd(__m128d a,int64_t b)3992*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cvtsi64_sd(__m128d a, int64_t b)
3993*35ffd701SAndroid Build Coastguard Worker {
3994*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
3995*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
3996*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f64((double) b, vreinterpretq_f64_m128d(a), 0));
3997*35ffd701SAndroid Build Coastguard Worker #else
3998*35ffd701SAndroid Build Coastguard Worker double bf = (double) b;
3999*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(
4000*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s64(*(int64_t *) &bf, vreinterpretq_s64_m128d(a), 0));
4001*35ffd701SAndroid Build Coastguard Worker #endif
4002*35ffd701SAndroid Build Coastguard Worker }
4003*35ffd701SAndroid Build Coastguard Worker
4004*35ffd701SAndroid Build Coastguard Worker // Moves 64-bit integer a to the least significant 64 bits of an __m128 object,
4005*35ffd701SAndroid Build Coastguard Worker // zero extending the upper bits.
4006*35ffd701SAndroid Build Coastguard Worker //
4007*35ffd701SAndroid Build Coastguard Worker // r0 := a
4008*35ffd701SAndroid Build Coastguard Worker // r1 := 0x0
_mm_cvtsi64_si128(int64_t a)4009*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtsi64_si128(int64_t a)
4010*35ffd701SAndroid Build Coastguard Worker {
4011*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vsetq_lane_s64(a, vdupq_n_s64(0), 0));
4012*35ffd701SAndroid Build Coastguard Worker }
4013*35ffd701SAndroid Build Coastguard Worker
4014*35ffd701SAndroid Build Coastguard Worker // Copy 64-bit integer a to the lower element of dst, and zero the upper
4015*35ffd701SAndroid Build Coastguard Worker // element.
4016*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64x_si128
4017*35ffd701SAndroid Build Coastguard Worker #define _mm_cvtsi64x_si128(a) _mm_cvtsi64_si128(a)
4018*35ffd701SAndroid Build Coastguard Worker
4019*35ffd701SAndroid Build Coastguard Worker // Convert the signed 64-bit integer b to a double-precision (64-bit)
4020*35ffd701SAndroid Build Coastguard Worker // floating-point element, store the result in the lower element of dst, and
4021*35ffd701SAndroid Build Coastguard Worker // copy the upper element from a to the upper element of dst.
4022*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64x_sd
4023*35ffd701SAndroid Build Coastguard Worker #define _mm_cvtsi64x_sd(a, b) _mm_cvtsi64_sd(a, b)
4024*35ffd701SAndroid Build Coastguard Worker
4025*35ffd701SAndroid Build Coastguard Worker // Convert the lower single-precision (32-bit) floating-point element in b to a
4026*35ffd701SAndroid Build Coastguard Worker // double-precision (64-bit) floating-point element, store the result in the
4027*35ffd701SAndroid Build Coastguard Worker // lower element of dst, and copy the upper element from a to the upper element
4028*35ffd701SAndroid Build Coastguard Worker // of dst.
4029*35ffd701SAndroid Build Coastguard Worker //
4030*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := Convert_FP32_To_FP64(b[31:0])
4031*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := a[127:64]
4032*35ffd701SAndroid Build Coastguard Worker //
4033*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_sd
_mm_cvtss_sd(__m128d a,__m128 b)4034*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_cvtss_sd(__m128d a, __m128 b)
4035*35ffd701SAndroid Build Coastguard Worker {
4036*35ffd701SAndroid Build Coastguard Worker double d = (double) vgetq_lane_f32(vreinterpretq_f32_m128(b), 0);
4037*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4038*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
4039*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f64(d, vreinterpretq_f64_m128d(a), 0));
4040*35ffd701SAndroid Build Coastguard Worker #else
4041*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(
4042*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s64(*(int64_t *) &d, vreinterpretq_s64_m128d(a), 0));
4043*35ffd701SAndroid Build Coastguard Worker #endif
4044*35ffd701SAndroid Build Coastguard Worker }
4045*35ffd701SAndroid Build Coastguard Worker
4046*35ffd701SAndroid Build Coastguard Worker // Convert packed double-precision (64-bit) floating-point elements in a to
4047*35ffd701SAndroid Build Coastguard Worker // packed 32-bit integers with truncation, and store the results in dst.
4048*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttpd_epi32
_mm_cvttpd_epi32(__m128d a)4049*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvttpd_epi32(__m128d a)
4050*35ffd701SAndroid Build Coastguard Worker {
4051*35ffd701SAndroid Build Coastguard Worker double a0 = ((double *) &a)[0];
4052*35ffd701SAndroid Build Coastguard Worker double a1 = ((double *) &a)[1];
4053*35ffd701SAndroid Build Coastguard Worker return _mm_set_epi32(0, 0, (int32_t) a1, (int32_t) a0);
4054*35ffd701SAndroid Build Coastguard Worker }
4055*35ffd701SAndroid Build Coastguard Worker
4056*35ffd701SAndroid Build Coastguard Worker // Convert packed double-precision (64-bit) floating-point elements in a to
4057*35ffd701SAndroid Build Coastguard Worker // packed 32-bit integers with truncation, and store the results in dst.
4058*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttpd_pi32
_mm_cvttpd_pi32(__m128d a)4059*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_cvttpd_pi32(__m128d a)
4060*35ffd701SAndroid Build Coastguard Worker {
4061*35ffd701SAndroid Build Coastguard Worker double a0 = ((double *) &a)[0];
4062*35ffd701SAndroid Build Coastguard Worker double a1 = ((double *) &a)[1];
4063*35ffd701SAndroid Build Coastguard Worker int32_t ALIGN_STRUCT(16) data[2] = {(int32_t) a0, (int32_t) a1};
4064*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(vld1_s32(data));
4065*35ffd701SAndroid Build Coastguard Worker }
4066*35ffd701SAndroid Build Coastguard Worker
4067*35ffd701SAndroid Build Coastguard Worker // Converts the four single-precision, floating-point values of a to signed
4068*35ffd701SAndroid Build Coastguard Worker // 32-bit integer values using truncate.
4069*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/1h005y6x(v=vs.100).aspx
_mm_cvttps_epi32(__m128 a)4070*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a)
4071*35ffd701SAndroid Build Coastguard Worker {
4072*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)));
4073*35ffd701SAndroid Build Coastguard Worker }
4074*35ffd701SAndroid Build Coastguard Worker
4075*35ffd701SAndroid Build Coastguard Worker // Convert the lower double-precision (64-bit) floating-point element in a to a
4076*35ffd701SAndroid Build Coastguard Worker // 32-bit integer with truncation, and store the result in dst.
4077*35ffd701SAndroid Build Coastguard Worker //
4078*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := Convert_FP64_To_Int32_Truncate(a[63:0])
4079*35ffd701SAndroid Build Coastguard Worker //
4080*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si32
_mm_cvttsd_si32(__m128d a)4081*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int32_t _mm_cvttsd_si32(__m128d a)
4082*35ffd701SAndroid Build Coastguard Worker {
4083*35ffd701SAndroid Build Coastguard Worker double ret = *((double *) &a);
4084*35ffd701SAndroid Build Coastguard Worker return (int32_t) ret;
4085*35ffd701SAndroid Build Coastguard Worker }
4086*35ffd701SAndroid Build Coastguard Worker
4087*35ffd701SAndroid Build Coastguard Worker // Convert the lower double-precision (64-bit) floating-point element in a to a
4088*35ffd701SAndroid Build Coastguard Worker // 64-bit integer with truncation, and store the result in dst.
4089*35ffd701SAndroid Build Coastguard Worker //
4090*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0])
4091*35ffd701SAndroid Build Coastguard Worker //
4092*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64
_mm_cvttsd_si64(__m128d a)4093*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int64_t _mm_cvttsd_si64(__m128d a)
4094*35ffd701SAndroid Build Coastguard Worker {
4095*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4096*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_s64(vcvtq_s64_f64(vreinterpretq_f64_m128d(a)), 0);
4097*35ffd701SAndroid Build Coastguard Worker #else
4098*35ffd701SAndroid Build Coastguard Worker double ret = *((double *) &a);
4099*35ffd701SAndroid Build Coastguard Worker return (int64_t) ret;
4100*35ffd701SAndroid Build Coastguard Worker #endif
4101*35ffd701SAndroid Build Coastguard Worker }
4102*35ffd701SAndroid Build Coastguard Worker
4103*35ffd701SAndroid Build Coastguard Worker // Convert the lower double-precision (64-bit) floating-point element in a to a
4104*35ffd701SAndroid Build Coastguard Worker // 64-bit integer with truncation, and store the result in dst.
4105*35ffd701SAndroid Build Coastguard Worker //
4106*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0])
4107*35ffd701SAndroid Build Coastguard Worker //
4108*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64x
4109*35ffd701SAndroid Build Coastguard Worker #define _mm_cvttsd_si64x(a) _mm_cvttsd_si64(a)
4110*35ffd701SAndroid Build Coastguard Worker
4111*35ffd701SAndroid Build Coastguard Worker // Divide packed double-precision (64-bit) floating-point elements in a by
4112*35ffd701SAndroid Build Coastguard Worker // packed elements in b, and store the results in dst.
4113*35ffd701SAndroid Build Coastguard Worker //
4114*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
4115*35ffd701SAndroid Build Coastguard Worker // i := 64*j
4116*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := a[i+63:i] / b[i+63:i]
4117*35ffd701SAndroid Build Coastguard Worker // ENDFOR
4118*35ffd701SAndroid Build Coastguard Worker //
4119*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_div_pd
_mm_div_pd(__m128d a,__m128d b)4120*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_div_pd(__m128d a, __m128d b)
4121*35ffd701SAndroid Build Coastguard Worker {
4122*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4123*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
4124*35ffd701SAndroid Build Coastguard Worker vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
4125*35ffd701SAndroid Build Coastguard Worker #else
4126*35ffd701SAndroid Build Coastguard Worker double *da = (double *) &a;
4127*35ffd701SAndroid Build Coastguard Worker double *db = (double *) &b;
4128*35ffd701SAndroid Build Coastguard Worker double c[2];
4129*35ffd701SAndroid Build Coastguard Worker c[0] = da[0] / db[0];
4130*35ffd701SAndroid Build Coastguard Worker c[1] = da[1] / db[1];
4131*35ffd701SAndroid Build Coastguard Worker return vld1q_f32((float32_t *) c);
4132*35ffd701SAndroid Build Coastguard Worker #endif
4133*35ffd701SAndroid Build Coastguard Worker }
4134*35ffd701SAndroid Build Coastguard Worker
4135*35ffd701SAndroid Build Coastguard Worker // Divide the lower double-precision (64-bit) floating-point element in a by the
4136*35ffd701SAndroid Build Coastguard Worker // lower double-precision (64-bit) floating-point element in b, store the result
4137*35ffd701SAndroid Build Coastguard Worker // in the lower element of dst, and copy the upper element from a to the upper
4138*35ffd701SAndroid Build Coastguard Worker // element of dst.
4139*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_div_sd
_mm_div_sd(__m128d a,__m128d b)4140*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_div_sd(__m128d a, __m128d b)
4141*35ffd701SAndroid Build Coastguard Worker {
4142*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4143*35ffd701SAndroid Build Coastguard Worker float64x2_t tmp =
4144*35ffd701SAndroid Build Coastguard Worker vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b));
4145*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
4146*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f64(vgetq_lane_f64(vreinterpretq_f64_m128d(a), 1), tmp, 1));
4147*35ffd701SAndroid Build Coastguard Worker #else
4148*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_div_pd(a, b));
4149*35ffd701SAndroid Build Coastguard Worker #endif
4150*35ffd701SAndroid Build Coastguard Worker }
4151*35ffd701SAndroid Build Coastguard Worker
4152*35ffd701SAndroid Build Coastguard Worker // Extracts the selected signed or unsigned 16-bit integer from a and zero
4153*35ffd701SAndroid Build Coastguard Worker // extends.
4154*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/6dceta0c(v=vs.100).aspx
4155*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE int _mm_extract_epi16(__m128i a, __constrange(0,8) int imm)
4156*35ffd701SAndroid Build Coastguard Worker #define _mm_extract_epi16(a, imm) \
4157*35ffd701SAndroid Build Coastguard Worker vgetq_lane_u16(vreinterpretq_u16_m128i(a), (imm))
4158*35ffd701SAndroid Build Coastguard Worker
4159*35ffd701SAndroid Build Coastguard Worker // Inserts the least significant 16 bits of b into the selected 16-bit integer
4160*35ffd701SAndroid Build Coastguard Worker // of a.
4161*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/kaze8hz1%28v=vs.100%29.aspx
4162*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_insert_epi16(__m128i a, int b,
4163*35ffd701SAndroid Build Coastguard Worker // __constrange(0,8) int imm)
4164*35ffd701SAndroid Build Coastguard Worker #define _mm_insert_epi16(a, b, imm) \
4165*35ffd701SAndroid Build Coastguard Worker __extension__({ \
4166*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s16( \
4167*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))); \
4168*35ffd701SAndroid Build Coastguard Worker })
4169*35ffd701SAndroid Build Coastguard Worker
4170*35ffd701SAndroid Build Coastguard Worker // Loads two double-precision from 16-byte aligned memory, floating-point
4171*35ffd701SAndroid Build Coastguard Worker // values.
4172*35ffd701SAndroid Build Coastguard Worker //
4173*35ffd701SAndroid Build Coastguard Worker // dst[127:0] := MEM[mem_addr+127:mem_addr]
4174*35ffd701SAndroid Build Coastguard Worker //
4175*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd
_mm_load_pd(const double * p)4176*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_load_pd(const double *p)
4177*35ffd701SAndroid Build Coastguard Worker {
4178*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4179*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vld1q_f64(p));
4180*35ffd701SAndroid Build Coastguard Worker #else
4181*35ffd701SAndroid Build Coastguard Worker const float *fp = (const float *) p;
4182*35ffd701SAndroid Build Coastguard Worker float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], fp[2], fp[3]};
4183*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f32(vld1q_f32(data));
4184*35ffd701SAndroid Build Coastguard Worker #endif
4185*35ffd701SAndroid Build Coastguard Worker }
4186*35ffd701SAndroid Build Coastguard Worker
4187*35ffd701SAndroid Build Coastguard Worker // Load a double-precision (64-bit) floating-point element from memory into both
4188*35ffd701SAndroid Build Coastguard Worker // elements of dst.
4189*35ffd701SAndroid Build Coastguard Worker //
4190*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := MEM[mem_addr+63:mem_addr]
4191*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := MEM[mem_addr+63:mem_addr]
4192*35ffd701SAndroid Build Coastguard Worker //
4193*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1
4194*35ffd701SAndroid Build Coastguard Worker #define _mm_load_pd1 _mm_load1_pd
4195*35ffd701SAndroid Build Coastguard Worker
4196*35ffd701SAndroid Build Coastguard Worker // Load a double-precision (64-bit) floating-point element from memory into the
4197*35ffd701SAndroid Build Coastguard Worker // lower of dst, and zero the upper element. mem_addr does not need to be
4198*35ffd701SAndroid Build Coastguard Worker // aligned on any particular boundary.
4199*35ffd701SAndroid Build Coastguard Worker //
4200*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := MEM[mem_addr+63:mem_addr]
4201*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := 0
4202*35ffd701SAndroid Build Coastguard Worker //
4203*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_sd
_mm_load_sd(const double * p)4204*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_load_sd(const double *p)
4205*35ffd701SAndroid Build Coastguard Worker {
4206*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4207*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vsetq_lane_f64(*p, vdupq_n_f64(0), 0));
4208*35ffd701SAndroid Build Coastguard Worker #else
4209*35ffd701SAndroid Build Coastguard Worker const float *fp = (const float *) p;
4210*35ffd701SAndroid Build Coastguard Worker float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], 0, 0};
4211*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f32(vld1q_f32(data));
4212*35ffd701SAndroid Build Coastguard Worker #endif
4213*35ffd701SAndroid Build Coastguard Worker }
4214*35ffd701SAndroid Build Coastguard Worker
4215*35ffd701SAndroid Build Coastguard Worker // Loads 128-bit value. :
4216*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/atzzad1h(v=vs.80).aspx
_mm_load_si128(const __m128i * p)4217*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_load_si128(const __m128i *p)
4218*35ffd701SAndroid Build Coastguard Worker {
4219*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p));
4220*35ffd701SAndroid Build Coastguard Worker }
4221*35ffd701SAndroid Build Coastguard Worker
4222*35ffd701SAndroid Build Coastguard Worker // Load a double-precision (64-bit) floating-point element from memory into both
4223*35ffd701SAndroid Build Coastguard Worker // elements of dst.
4224*35ffd701SAndroid Build Coastguard Worker //
4225*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := MEM[mem_addr+63:mem_addr]
4226*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := MEM[mem_addr+63:mem_addr]
4227*35ffd701SAndroid Build Coastguard Worker //
4228*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load1_pd
_mm_load1_pd(const double * p)4229*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_load1_pd(const double *p)
4230*35ffd701SAndroid Build Coastguard Worker {
4231*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4232*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vld1q_dup_f64(p));
4233*35ffd701SAndroid Build Coastguard Worker #else
4234*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(vdupq_n_s64(*(const int64_t *) p));
4235*35ffd701SAndroid Build Coastguard Worker #endif
4236*35ffd701SAndroid Build Coastguard Worker }
4237*35ffd701SAndroid Build Coastguard Worker
4238*35ffd701SAndroid Build Coastguard Worker // Load a double-precision (64-bit) floating-point element from memory into the
4239*35ffd701SAndroid Build Coastguard Worker // upper element of dst, and copy the lower element from a to dst. mem_addr does
4240*35ffd701SAndroid Build Coastguard Worker // not need to be aligned on any particular boundary.
4241*35ffd701SAndroid Build Coastguard Worker //
4242*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0]
4243*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := MEM[mem_addr+63:mem_addr]
4244*35ffd701SAndroid Build Coastguard Worker //
4245*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadh_pd
_mm_loadh_pd(__m128d a,const double * p)4246*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_loadh_pd(__m128d a, const double *p)
4247*35ffd701SAndroid Build Coastguard Worker {
4248*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4249*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
4250*35ffd701SAndroid Build Coastguard Worker vcombine_f64(vget_low_f64(vreinterpretq_f64_m128d(a)), vld1_f64(p)));
4251*35ffd701SAndroid Build Coastguard Worker #else
4252*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f32(vcombine_f32(
4253*35ffd701SAndroid Build Coastguard Worker vget_low_f32(vreinterpretq_f32_m128d(a)), vld1_f32((const float *) p)));
4254*35ffd701SAndroid Build Coastguard Worker #endif
4255*35ffd701SAndroid Build Coastguard Worker }
4256*35ffd701SAndroid Build Coastguard Worker
4257*35ffd701SAndroid Build Coastguard Worker // Load 64-bit integer from memory into the first element of dst.
4258*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_epi64
_mm_loadl_epi64(__m128i const * p)4259*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_loadl_epi64(__m128i const *p)
4260*35ffd701SAndroid Build Coastguard Worker {
4261*35ffd701SAndroid Build Coastguard Worker /* Load the lower 64 bits of the value pointed to by p into the
4262*35ffd701SAndroid Build Coastguard Worker * lower 64 bits of the result, zeroing the upper 64 bits of the result.
4263*35ffd701SAndroid Build Coastguard Worker */
4264*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
4265*35ffd701SAndroid Build Coastguard Worker vcombine_s32(vld1_s32((int32_t const *) p), vcreate_s32(0)));
4266*35ffd701SAndroid Build Coastguard Worker }
4267*35ffd701SAndroid Build Coastguard Worker
4268*35ffd701SAndroid Build Coastguard Worker // Load a double-precision (64-bit) floating-point element from memory into the
4269*35ffd701SAndroid Build Coastguard Worker // lower element of dst, and copy the upper element from a to dst. mem_addr does
4270*35ffd701SAndroid Build Coastguard Worker // not need to be aligned on any particular boundary.
4271*35ffd701SAndroid Build Coastguard Worker //
4272*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := MEM[mem_addr+63:mem_addr]
4273*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := a[127:64]
4274*35ffd701SAndroid Build Coastguard Worker //
4275*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_pd
_mm_loadl_pd(__m128d a,const double * p)4276*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_loadl_pd(__m128d a, const double *p)
4277*35ffd701SAndroid Build Coastguard Worker {
4278*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4279*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
4280*35ffd701SAndroid Build Coastguard Worker vcombine_f64(vld1_f64(p), vget_high_f64(vreinterpretq_f64_m128d(a))));
4281*35ffd701SAndroid Build Coastguard Worker #else
4282*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f32(
4283*35ffd701SAndroid Build Coastguard Worker vcombine_f32(vld1_f32((const float *) p),
4284*35ffd701SAndroid Build Coastguard Worker vget_high_f32(vreinterpretq_f32_m128d(a))));
4285*35ffd701SAndroid Build Coastguard Worker #endif
4286*35ffd701SAndroid Build Coastguard Worker }
4287*35ffd701SAndroid Build Coastguard Worker
4288*35ffd701SAndroid Build Coastguard Worker // Load 2 double-precision (64-bit) floating-point elements from memory into dst
4289*35ffd701SAndroid Build Coastguard Worker // in reverse order. mem_addr must be aligned on a 16-byte boundary or a
4290*35ffd701SAndroid Build Coastguard Worker // general-protection exception may be generated.
4291*35ffd701SAndroid Build Coastguard Worker //
4292*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := MEM[mem_addr+127:mem_addr+64]
4293*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := MEM[mem_addr+63:mem_addr]
4294*35ffd701SAndroid Build Coastguard Worker //
4295*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_pd
_mm_loadr_pd(const double * p)4296*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_loadr_pd(const double *p)
4297*35ffd701SAndroid Build Coastguard Worker {
4298*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4299*35ffd701SAndroid Build Coastguard Worker float64x2_t v = vld1q_f64(p);
4300*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vextq_f64(v, v, 1));
4301*35ffd701SAndroid Build Coastguard Worker #else
4302*35ffd701SAndroid Build Coastguard Worker int64x2_t v = vld1q_s64((const int64_t *) p);
4303*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(vextq_s64(v, v, 1));
4304*35ffd701SAndroid Build Coastguard Worker #endif
4305*35ffd701SAndroid Build Coastguard Worker }
4306*35ffd701SAndroid Build Coastguard Worker
4307*35ffd701SAndroid Build Coastguard Worker // Loads two double-precision from unaligned memory, floating-point values.
4308*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_pd
_mm_loadu_pd(const double * p)4309*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_loadu_pd(const double *p)
4310*35ffd701SAndroid Build Coastguard Worker {
4311*35ffd701SAndroid Build Coastguard Worker return _mm_load_pd(p);
4312*35ffd701SAndroid Build Coastguard Worker }
4313*35ffd701SAndroid Build Coastguard Worker
4314*35ffd701SAndroid Build Coastguard Worker // Loads 128-bit value. :
4315*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/zh-cn/library/f4k12ae8(v=vs.90).aspx
_mm_loadu_si128(const __m128i * p)4316*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_loadu_si128(const __m128i *p)
4317*35ffd701SAndroid Build Coastguard Worker {
4318*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p));
4319*35ffd701SAndroid Build Coastguard Worker }
4320*35ffd701SAndroid Build Coastguard Worker
4321*35ffd701SAndroid Build Coastguard Worker // Load unaligned 32-bit integer from memory into the first element of dst.
4322*35ffd701SAndroid Build Coastguard Worker //
4323*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := MEM[mem_addr+31:mem_addr]
4324*35ffd701SAndroid Build Coastguard Worker // dst[MAX:32] := 0
4325*35ffd701SAndroid Build Coastguard Worker //
4326*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si32
_mm_loadu_si32(const void * p)4327*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_loadu_si32(const void *p)
4328*35ffd701SAndroid Build Coastguard Worker {
4329*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
4330*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s32(*(const int32_t *) p, vdupq_n_s32(0), 0));
4331*35ffd701SAndroid Build Coastguard Worker }
4332*35ffd701SAndroid Build Coastguard Worker
4333*35ffd701SAndroid Build Coastguard Worker // Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit
4334*35ffd701SAndroid Build Coastguard Worker // integers from b.
4335*35ffd701SAndroid Build Coastguard Worker //
4336*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 * b0) + (a1 * b1)
4337*35ffd701SAndroid Build Coastguard Worker // r1 := (a2 * b2) + (a3 * b3)
4338*35ffd701SAndroid Build Coastguard Worker // r2 := (a4 * b4) + (a5 * b5)
4339*35ffd701SAndroid Build Coastguard Worker // r3 := (a6 * b6) + (a7 * b7)
4340*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/yht36sa6(v=vs.90).aspx
_mm_madd_epi16(__m128i a,__m128i b)4341*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b)
4342*35ffd701SAndroid Build Coastguard Worker {
4343*35ffd701SAndroid Build Coastguard Worker int32x4_t low = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)),
4344*35ffd701SAndroid Build Coastguard Worker vget_low_s16(vreinterpretq_s16_m128i(b)));
4345*35ffd701SAndroid Build Coastguard Worker int32x4_t high = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)),
4346*35ffd701SAndroid Build Coastguard Worker vget_high_s16(vreinterpretq_s16_m128i(b)));
4347*35ffd701SAndroid Build Coastguard Worker
4348*35ffd701SAndroid Build Coastguard Worker int32x2_t low_sum = vpadd_s32(vget_low_s32(low), vget_high_s32(low));
4349*35ffd701SAndroid Build Coastguard Worker int32x2_t high_sum = vpadd_s32(vget_low_s32(high), vget_high_s32(high));
4350*35ffd701SAndroid Build Coastguard Worker
4351*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(low_sum, high_sum));
4352*35ffd701SAndroid Build Coastguard Worker }
4353*35ffd701SAndroid Build Coastguard Worker
4354*35ffd701SAndroid Build Coastguard Worker // Conditionally store 8-bit integer elements from a into memory using mask
4355*35ffd701SAndroid Build Coastguard Worker // (elements are not stored when the highest bit is not set in the corresponding
4356*35ffd701SAndroid Build Coastguard Worker // element) and a non-temporal memory hint. mem_addr does not need to be aligned
4357*35ffd701SAndroid Build Coastguard Worker // on any particular boundary.
4358*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskmoveu_si128
_mm_maskmoveu_si128(__m128i a,__m128i mask,char * mem_addr)4359*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_maskmoveu_si128(__m128i a, __m128i mask, char *mem_addr)
4360*35ffd701SAndroid Build Coastguard Worker {
4361*35ffd701SAndroid Build Coastguard Worker int8x16_t shr_mask = vshrq_n_s8(vreinterpretq_s8_m128i(mask), 7);
4362*35ffd701SAndroid Build Coastguard Worker __m128 b = _mm_load_ps((const float *) mem_addr);
4363*35ffd701SAndroid Build Coastguard Worker int8x16_t masked =
4364*35ffd701SAndroid Build Coastguard Worker vbslq_s8(vreinterpretq_u8_s8(shr_mask), vreinterpretq_s8_m128i(a),
4365*35ffd701SAndroid Build Coastguard Worker vreinterpretq_s8_m128(b));
4366*35ffd701SAndroid Build Coastguard Worker vst1q_s8((int8_t *) mem_addr, masked);
4367*35ffd701SAndroid Build Coastguard Worker }
4368*35ffd701SAndroid Build Coastguard Worker
4369*35ffd701SAndroid Build Coastguard Worker // Computes the pairwise maxima of the 8 signed 16-bit integers from a and the 8
4370*35ffd701SAndroid Build Coastguard Worker // signed 16-bit integers from b.
4371*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/LIBRary/3x060h7c(v=vs.100).aspx
_mm_max_epi16(__m128i a,__m128i b)4372*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_max_epi16(__m128i a, __m128i b)
4373*35ffd701SAndroid Build Coastguard Worker {
4374*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
4375*35ffd701SAndroid Build Coastguard Worker vmaxq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
4376*35ffd701SAndroid Build Coastguard Worker }
4377*35ffd701SAndroid Build Coastguard Worker
4378*35ffd701SAndroid Build Coastguard Worker // Computes the pairwise maxima of the 16 unsigned 8-bit integers from a and the
4379*35ffd701SAndroid Build Coastguard Worker // 16 unsigned 8-bit integers from b.
4380*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/st6634za(v=vs.100).aspx
_mm_max_epu8(__m128i a,__m128i b)4381*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_max_epu8(__m128i a, __m128i b)
4382*35ffd701SAndroid Build Coastguard Worker {
4383*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
4384*35ffd701SAndroid Build Coastguard Worker vmaxq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b)));
4385*35ffd701SAndroid Build Coastguard Worker }
4386*35ffd701SAndroid Build Coastguard Worker
4387*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b,
4388*35ffd701SAndroid Build Coastguard Worker // and store packed maximum values in dst.
4389*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pd
_mm_max_pd(__m128d a,__m128d b)4390*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_max_pd(__m128d a, __m128d b)
4391*35ffd701SAndroid Build Coastguard Worker {
4392*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4393*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
4394*35ffd701SAndroid Build Coastguard Worker vmaxq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
4395*35ffd701SAndroid Build Coastguard Worker #else
4396*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
4397*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
4398*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
4399*35ffd701SAndroid Build Coastguard Worker uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
4400*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
4401*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) > (*(double *) &b0) ? a0 : b0;
4402*35ffd701SAndroid Build Coastguard Worker d[1] = (*(double *) &a1) > (*(double *) &b1) ? a1 : b1;
4403*35ffd701SAndroid Build Coastguard Worker
4404*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
4405*35ffd701SAndroid Build Coastguard Worker #endif
4406*35ffd701SAndroid Build Coastguard Worker }
4407*35ffd701SAndroid Build Coastguard Worker
4408*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
4409*35ffd701SAndroid Build Coastguard Worker // b, store the maximum value in the lower element of dst, and copy the upper
4410*35ffd701SAndroid Build Coastguard Worker // element from a to the upper element of dst.
4411*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_sd
_mm_max_sd(__m128d a,__m128d b)4412*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_max_sd(__m128d a, __m128d b)
4413*35ffd701SAndroid Build Coastguard Worker {
4414*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4415*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_max_pd(a, b));
4416*35ffd701SAndroid Build Coastguard Worker #else
4417*35ffd701SAndroid Build Coastguard Worker double *da = (double *) &a;
4418*35ffd701SAndroid Build Coastguard Worker double *db = (double *) &b;
4419*35ffd701SAndroid Build Coastguard Worker double c[2] = {fmax(da[0], db[0]), da[1]};
4420*35ffd701SAndroid Build Coastguard Worker return vld1q_f32((float32_t *) c);
4421*35ffd701SAndroid Build Coastguard Worker #endif
4422*35ffd701SAndroid Build Coastguard Worker }
4423*35ffd701SAndroid Build Coastguard Worker
4424*35ffd701SAndroid Build Coastguard Worker // Computes the pairwise minima of the 8 signed 16-bit integers from a and the 8
4425*35ffd701SAndroid Build Coastguard Worker // signed 16-bit integers from b.
4426*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/6te997ew(v=vs.100).aspx
_mm_min_epi16(__m128i a,__m128i b)4427*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_min_epi16(__m128i a, __m128i b)
4428*35ffd701SAndroid Build Coastguard Worker {
4429*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
4430*35ffd701SAndroid Build Coastguard Worker vminq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
4431*35ffd701SAndroid Build Coastguard Worker }
4432*35ffd701SAndroid Build Coastguard Worker
4433*35ffd701SAndroid Build Coastguard Worker // Computes the pairwise minima of the 16 unsigned 8-bit integers from a and the
4434*35ffd701SAndroid Build Coastguard Worker // 16 unsigned 8-bit integers from b.
4435*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/ko-kr/library/17k8cf58(v=vs.100).aspxx
_mm_min_epu8(__m128i a,__m128i b)4436*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b)
4437*35ffd701SAndroid Build Coastguard Worker {
4438*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
4439*35ffd701SAndroid Build Coastguard Worker vminq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b)));
4440*35ffd701SAndroid Build Coastguard Worker }
4441*35ffd701SAndroid Build Coastguard Worker
4442*35ffd701SAndroid Build Coastguard Worker // Compare packed double-precision (64-bit) floating-point elements in a and b,
4443*35ffd701SAndroid Build Coastguard Worker // and store packed minimum values in dst.
4444*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pd
_mm_min_pd(__m128d a,__m128d b)4445*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_min_pd(__m128d a, __m128d b)
4446*35ffd701SAndroid Build Coastguard Worker {
4447*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4448*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
4449*35ffd701SAndroid Build Coastguard Worker vminq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
4450*35ffd701SAndroid Build Coastguard Worker #else
4451*35ffd701SAndroid Build Coastguard Worker uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a));
4452*35ffd701SAndroid Build Coastguard Worker uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a));
4453*35ffd701SAndroid Build Coastguard Worker uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b));
4454*35ffd701SAndroid Build Coastguard Worker uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b));
4455*35ffd701SAndroid Build Coastguard Worker uint64_t d[2];
4456*35ffd701SAndroid Build Coastguard Worker d[0] = (*(double *) &a0) < (*(double *) &b0) ? a0 : b0;
4457*35ffd701SAndroid Build Coastguard Worker d[1] = (*(double *) &a1) < (*(double *) &b1) ? a1 : b1;
4458*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64(d));
4459*35ffd701SAndroid Build Coastguard Worker #endif
4460*35ffd701SAndroid Build Coastguard Worker }
4461*35ffd701SAndroid Build Coastguard Worker
4462*35ffd701SAndroid Build Coastguard Worker // Compare the lower double-precision (64-bit) floating-point elements in a and
4463*35ffd701SAndroid Build Coastguard Worker // b, store the minimum value in the lower element of dst, and copy the upper
4464*35ffd701SAndroid Build Coastguard Worker // element from a to the upper element of dst.
4465*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_sd
_mm_min_sd(__m128d a,__m128d b)4466*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_min_sd(__m128d a, __m128d b)
4467*35ffd701SAndroid Build Coastguard Worker {
4468*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4469*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_min_pd(a, b));
4470*35ffd701SAndroid Build Coastguard Worker #else
4471*35ffd701SAndroid Build Coastguard Worker double *da = (double *) &a;
4472*35ffd701SAndroid Build Coastguard Worker double *db = (double *) &b;
4473*35ffd701SAndroid Build Coastguard Worker double c[2] = {fmin(da[0], db[0]), da[1]};
4474*35ffd701SAndroid Build Coastguard Worker return vld1q_f32((float32_t *) c);
4475*35ffd701SAndroid Build Coastguard Worker #endif
4476*35ffd701SAndroid Build Coastguard Worker }
4477*35ffd701SAndroid Build Coastguard Worker
4478*35ffd701SAndroid Build Coastguard Worker // Copy the lower 64-bit integer in a to the lower element of dst, and zero the
4479*35ffd701SAndroid Build Coastguard Worker // upper element.
4480*35ffd701SAndroid Build Coastguard Worker //
4481*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0]
4482*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := 0
4483*35ffd701SAndroid Build Coastguard Worker //
4484*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_epi64
_mm_move_epi64(__m128i a)4485*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_move_epi64(__m128i a)
4486*35ffd701SAndroid Build Coastguard Worker {
4487*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(
4488*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s64(0, vreinterpretq_s64_m128i(a), 1));
4489*35ffd701SAndroid Build Coastguard Worker }
4490*35ffd701SAndroid Build Coastguard Worker
4491*35ffd701SAndroid Build Coastguard Worker // Move the lower double-precision (64-bit) floating-point element from b to the
4492*35ffd701SAndroid Build Coastguard Worker // lower element of dst, and copy the upper element from a to the upper element
4493*35ffd701SAndroid Build Coastguard Worker // of dst.
4494*35ffd701SAndroid Build Coastguard Worker //
4495*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := b[63:0]
4496*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := a[127:64]
4497*35ffd701SAndroid Build Coastguard Worker //
4498*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_sd
_mm_move_sd(__m128d a,__m128d b)4499*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_move_sd(__m128d a, __m128d b)
4500*35ffd701SAndroid Build Coastguard Worker {
4501*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f32(
4502*35ffd701SAndroid Build Coastguard Worker vcombine_f32(vget_low_f32(vreinterpretq_f32_m128d(b)),
4503*35ffd701SAndroid Build Coastguard Worker vget_high_f32(vreinterpretq_f32_m128d(a))));
4504*35ffd701SAndroid Build Coastguard Worker }
4505*35ffd701SAndroid Build Coastguard Worker
4506*35ffd701SAndroid Build Coastguard Worker // NEON does not provide a version of this function.
4507*35ffd701SAndroid Build Coastguard Worker // Creates a 16-bit mask from the most significant bits of the 16 signed or
4508*35ffd701SAndroid Build Coastguard Worker // unsigned 8-bit integers in a and zero extends the upper bits.
4509*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/s090c8fk(v=vs.100).aspx
_mm_movemask_epi8(__m128i a)4510*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_movemask_epi8(__m128i a)
4511*35ffd701SAndroid Build Coastguard Worker {
4512*35ffd701SAndroid Build Coastguard Worker // Use increasingly wide shifts+adds to collect the sign bits
4513*35ffd701SAndroid Build Coastguard Worker // together.
4514*35ffd701SAndroid Build Coastguard Worker // Since the widening shifts would be rather confusing to follow in little
4515*35ffd701SAndroid Build Coastguard Worker // endian, everything will be illustrated in big endian order instead. This
4516*35ffd701SAndroid Build Coastguard Worker // has a different result - the bits would actually be reversed on a big
4517*35ffd701SAndroid Build Coastguard Worker // endian machine.
4518*35ffd701SAndroid Build Coastguard Worker
4519*35ffd701SAndroid Build Coastguard Worker // Starting input (only half the elements are shown):
4520*35ffd701SAndroid Build Coastguard Worker // 89 ff 1d c0 00 10 99 33
4521*35ffd701SAndroid Build Coastguard Worker uint8x16_t input = vreinterpretq_u8_m128i(a);
4522*35ffd701SAndroid Build Coastguard Worker
4523*35ffd701SAndroid Build Coastguard Worker // Shift out everything but the sign bits with an unsigned shift right.
4524*35ffd701SAndroid Build Coastguard Worker //
4525*35ffd701SAndroid Build Coastguard Worker // Bytes of the vector::
4526*35ffd701SAndroid Build Coastguard Worker // 89 ff 1d c0 00 10 99 33
4527*35ffd701SAndroid Build Coastguard Worker // \ \ \ \ \ \ \ \ high_bits = (uint16x4_t)(input >> 7)
4528*35ffd701SAndroid Build Coastguard Worker // | | | | | | | |
4529*35ffd701SAndroid Build Coastguard Worker // 01 01 00 01 00 00 01 00
4530*35ffd701SAndroid Build Coastguard Worker //
4531*35ffd701SAndroid Build Coastguard Worker // Bits of first important lane(s):
4532*35ffd701SAndroid Build Coastguard Worker // 10001001 (89)
4533*35ffd701SAndroid Build Coastguard Worker // \______
4534*35ffd701SAndroid Build Coastguard Worker // |
4535*35ffd701SAndroid Build Coastguard Worker // 00000001 (01)
4536*35ffd701SAndroid Build Coastguard Worker uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(input, 7));
4537*35ffd701SAndroid Build Coastguard Worker
4538*35ffd701SAndroid Build Coastguard Worker // Merge the even lanes together with a 16-bit unsigned shift right + add.
4539*35ffd701SAndroid Build Coastguard Worker // 'xx' represents garbage data which will be ignored in the final result.
4540*35ffd701SAndroid Build Coastguard Worker // In the important bytes, the add functions like a binary OR.
4541*35ffd701SAndroid Build Coastguard Worker //
4542*35ffd701SAndroid Build Coastguard Worker // 01 01 00 01 00 00 01 00
4543*35ffd701SAndroid Build Coastguard Worker // \_ | \_ | \_ | \_ | paired16 = (uint32x4_t)(input + (input >> 7))
4544*35ffd701SAndroid Build Coastguard Worker // \| \| \| \|
4545*35ffd701SAndroid Build Coastguard Worker // xx 03 xx 01 xx 00 xx 02
4546*35ffd701SAndroid Build Coastguard Worker //
4547*35ffd701SAndroid Build Coastguard Worker // 00000001 00000001 (01 01)
4548*35ffd701SAndroid Build Coastguard Worker // \_______ |
4549*35ffd701SAndroid Build Coastguard Worker // \|
4550*35ffd701SAndroid Build Coastguard Worker // xxxxxxxx xxxxxx11 (xx 03)
4551*35ffd701SAndroid Build Coastguard Worker uint32x4_t paired16 =
4552*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7));
4553*35ffd701SAndroid Build Coastguard Worker
4554*35ffd701SAndroid Build Coastguard Worker // Repeat with a wider 32-bit shift + add.
4555*35ffd701SAndroid Build Coastguard Worker // xx 03 xx 01 xx 00 xx 02
4556*35ffd701SAndroid Build Coastguard Worker // \____ | \____ | paired32 = (uint64x1_t)(paired16 + (paired16 >>
4557*35ffd701SAndroid Build Coastguard Worker // 14))
4558*35ffd701SAndroid Build Coastguard Worker // \| \|
4559*35ffd701SAndroid Build Coastguard Worker // xx xx xx 0d xx xx xx 02
4560*35ffd701SAndroid Build Coastguard Worker //
4561*35ffd701SAndroid Build Coastguard Worker // 00000011 00000001 (03 01)
4562*35ffd701SAndroid Build Coastguard Worker // \\_____ ||
4563*35ffd701SAndroid Build Coastguard Worker // '----.\||
4564*35ffd701SAndroid Build Coastguard Worker // xxxxxxxx xxxx1101 (xx 0d)
4565*35ffd701SAndroid Build Coastguard Worker uint64x2_t paired32 =
4566*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14));
4567*35ffd701SAndroid Build Coastguard Worker
4568*35ffd701SAndroid Build Coastguard Worker // Last, an even wider 64-bit shift + add to get our result in the low 8 bit
4569*35ffd701SAndroid Build Coastguard Worker // lanes. xx xx xx 0d xx xx xx 02
4570*35ffd701SAndroid Build Coastguard Worker // \_________ | paired64 = (uint8x8_t)(paired32 + (paired32 >>
4571*35ffd701SAndroid Build Coastguard Worker // 28))
4572*35ffd701SAndroid Build Coastguard Worker // \|
4573*35ffd701SAndroid Build Coastguard Worker // xx xx xx xx xx xx xx d2
4574*35ffd701SAndroid Build Coastguard Worker //
4575*35ffd701SAndroid Build Coastguard Worker // 00001101 00000010 (0d 02)
4576*35ffd701SAndroid Build Coastguard Worker // \ \___ | |
4577*35ffd701SAndroid Build Coastguard Worker // '---. \| |
4578*35ffd701SAndroid Build Coastguard Worker // xxxxxxxx 11010010 (xx d2)
4579*35ffd701SAndroid Build Coastguard Worker uint8x16_t paired64 =
4580*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28));
4581*35ffd701SAndroid Build Coastguard Worker
4582*35ffd701SAndroid Build Coastguard Worker // Extract the low 8 bits from each 64-bit lane with 2 8-bit extracts.
4583*35ffd701SAndroid Build Coastguard Worker // xx xx xx xx xx xx xx d2
4584*35ffd701SAndroid Build Coastguard Worker // || return paired64[0]
4585*35ffd701SAndroid Build Coastguard Worker // d2
4586*35ffd701SAndroid Build Coastguard Worker // Note: Little endian would return the correct value 4b (01001011) instead.
4587*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8);
4588*35ffd701SAndroid Build Coastguard Worker }
4589*35ffd701SAndroid Build Coastguard Worker
4590*35ffd701SAndroid Build Coastguard Worker // Set each bit of mask dst based on the most significant bit of the
4591*35ffd701SAndroid Build Coastguard Worker // corresponding packed double-precision (64-bit) floating-point element in a.
4592*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movemask_pd
_mm_movemask_pd(__m128d a)4593*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_movemask_pd(__m128d a)
4594*35ffd701SAndroid Build Coastguard Worker {
4595*35ffd701SAndroid Build Coastguard Worker uint64x2_t input = vreinterpretq_u64_m128d(a);
4596*35ffd701SAndroid Build Coastguard Worker uint64x2_t high_bits = vshrq_n_u64(input, 63);
4597*35ffd701SAndroid Build Coastguard Worker return vgetq_lane_u64(high_bits, 0) | (vgetq_lane_u64(high_bits, 1) << 1);
4598*35ffd701SAndroid Build Coastguard Worker }
4599*35ffd701SAndroid Build Coastguard Worker
4600*35ffd701SAndroid Build Coastguard Worker // Copy the lower 64-bit integer in a to dst.
4601*35ffd701SAndroid Build Coastguard Worker //
4602*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0]
4603*35ffd701SAndroid Build Coastguard Worker //
4604*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movepi64_pi64
_mm_movepi64_pi64(__m128i a)4605*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_movepi64_pi64(__m128i a)
4606*35ffd701SAndroid Build Coastguard Worker {
4607*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s64(vget_low_s64(vreinterpretq_s64_m128i(a)));
4608*35ffd701SAndroid Build Coastguard Worker }
4609*35ffd701SAndroid Build Coastguard Worker
4610*35ffd701SAndroid Build Coastguard Worker // Copy the 64-bit integer a to the lower element of dst, and zero the upper
4611*35ffd701SAndroid Build Coastguard Worker // element.
4612*35ffd701SAndroid Build Coastguard Worker //
4613*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0]
4614*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := 0
4615*35ffd701SAndroid Build Coastguard Worker //
4616*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movpi64_epi64
_mm_movpi64_epi64(__m64 a)4617*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_movpi64_epi64(__m64 a)
4618*35ffd701SAndroid Build Coastguard Worker {
4619*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(
4620*35ffd701SAndroid Build Coastguard Worker vcombine_s64(vreinterpret_s64_m64(a), vdup_n_s64(0)));
4621*35ffd701SAndroid Build Coastguard Worker }
4622*35ffd701SAndroid Build Coastguard Worker
4623*35ffd701SAndroid Build Coastguard Worker // Multiply the low unsigned 32-bit integers from each packed 64-bit element in
4624*35ffd701SAndroid Build Coastguard Worker // a and b, and store the unsigned 64-bit results in dst.
4625*35ffd701SAndroid Build Coastguard Worker //
4626*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 & 0xFFFFFFFF) * (b0 & 0xFFFFFFFF)
4627*35ffd701SAndroid Build Coastguard Worker // r1 := (a2 & 0xFFFFFFFF) * (b2 & 0xFFFFFFFF)
_mm_mul_epu32(__m128i a,__m128i b)4628*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b)
4629*35ffd701SAndroid Build Coastguard Worker {
4630*35ffd701SAndroid Build Coastguard Worker // vmull_u32 upcasts instead of masking, so we downcast.
4631*35ffd701SAndroid Build Coastguard Worker uint32x2_t a_lo = vmovn_u64(vreinterpretq_u64_m128i(a));
4632*35ffd701SAndroid Build Coastguard Worker uint32x2_t b_lo = vmovn_u64(vreinterpretq_u64_m128i(b));
4633*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(vmull_u32(a_lo, b_lo));
4634*35ffd701SAndroid Build Coastguard Worker }
4635*35ffd701SAndroid Build Coastguard Worker
4636*35ffd701SAndroid Build Coastguard Worker // Multiply packed double-precision (64-bit) floating-point elements in a and b,
4637*35ffd701SAndroid Build Coastguard Worker // and store the results in dst.
4638*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_pd
_mm_mul_pd(__m128d a,__m128d b)4639*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_mul_pd(__m128d a, __m128d b)
4640*35ffd701SAndroid Build Coastguard Worker {
4641*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4642*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
4643*35ffd701SAndroid Build Coastguard Worker vmulq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
4644*35ffd701SAndroid Build Coastguard Worker #else
4645*35ffd701SAndroid Build Coastguard Worker double *da = (double *) &a;
4646*35ffd701SAndroid Build Coastguard Worker double *db = (double *) &b;
4647*35ffd701SAndroid Build Coastguard Worker double c[2];
4648*35ffd701SAndroid Build Coastguard Worker c[0] = da[0] * db[0];
4649*35ffd701SAndroid Build Coastguard Worker c[1] = da[1] * db[1];
4650*35ffd701SAndroid Build Coastguard Worker return vld1q_f32((float32_t *) c);
4651*35ffd701SAndroid Build Coastguard Worker #endif
4652*35ffd701SAndroid Build Coastguard Worker }
4653*35ffd701SAndroid Build Coastguard Worker
4654*35ffd701SAndroid Build Coastguard Worker // Multiply the lower double-precision (64-bit) floating-point element in a and
4655*35ffd701SAndroid Build Coastguard Worker // b, store the result in the lower element of dst, and copy the upper element
4656*35ffd701SAndroid Build Coastguard Worker // from a to the upper element of dst.
4657*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_mul_sd
_mm_mul_sd(__m128d a,__m128d b)4658*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_mul_sd(__m128d a, __m128d b)
4659*35ffd701SAndroid Build Coastguard Worker {
4660*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_mul_pd(a, b));
4661*35ffd701SAndroid Build Coastguard Worker }
4662*35ffd701SAndroid Build Coastguard Worker
4663*35ffd701SAndroid Build Coastguard Worker // Multiply the low unsigned 32-bit integers from a and b, and store the
4664*35ffd701SAndroid Build Coastguard Worker // unsigned 64-bit result in dst.
4665*35ffd701SAndroid Build Coastguard Worker //
4666*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[31:0] * b[31:0]
4667*35ffd701SAndroid Build Coastguard Worker //
4668*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_su32
_mm_mul_su32(__m64 a,__m64 b)4669*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_mul_su32(__m64 a, __m64 b)
4670*35ffd701SAndroid Build Coastguard Worker {
4671*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_u64(vget_low_u64(
4672*35ffd701SAndroid Build Coastguard Worker vmull_u32(vreinterpret_u32_m64(a), vreinterpret_u32_m64(b))));
4673*35ffd701SAndroid Build Coastguard Worker }
4674*35ffd701SAndroid Build Coastguard Worker
4675*35ffd701SAndroid Build Coastguard Worker // Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit
4676*35ffd701SAndroid Build Coastguard Worker // integers from b.
4677*35ffd701SAndroid Build Coastguard Worker //
4678*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 * b0)[31:16]
4679*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 * b1)[31:16]
4680*35ffd701SAndroid Build Coastguard Worker // ...
4681*35ffd701SAndroid Build Coastguard Worker // r7 := (a7 * b7)[31:16]
4682*35ffd701SAndroid Build Coastguard Worker //
4683*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/59hddw1d(v=vs.100).aspx
_mm_mulhi_epi16(__m128i a,__m128i b)4684*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b)
4685*35ffd701SAndroid Build Coastguard Worker {
4686*35ffd701SAndroid Build Coastguard Worker /* FIXME: issue with large values because of result saturation */
4687*35ffd701SAndroid Build Coastguard Worker // int16x8_t ret = vqdmulhq_s16(vreinterpretq_s16_m128i(a),
4688*35ffd701SAndroid Build Coastguard Worker // vreinterpretq_s16_m128i(b)); /* =2*a*b */ return
4689*35ffd701SAndroid Build Coastguard Worker // vreinterpretq_m128i_s16(vshrq_n_s16(ret, 1));
4690*35ffd701SAndroid Build Coastguard Worker int16x4_t a3210 = vget_low_s16(vreinterpretq_s16_m128i(a));
4691*35ffd701SAndroid Build Coastguard Worker int16x4_t b3210 = vget_low_s16(vreinterpretq_s16_m128i(b));
4692*35ffd701SAndroid Build Coastguard Worker int32x4_t ab3210 = vmull_s16(a3210, b3210); /* 3333222211110000 */
4693*35ffd701SAndroid Build Coastguard Worker int16x4_t a7654 = vget_high_s16(vreinterpretq_s16_m128i(a));
4694*35ffd701SAndroid Build Coastguard Worker int16x4_t b7654 = vget_high_s16(vreinterpretq_s16_m128i(b));
4695*35ffd701SAndroid Build Coastguard Worker int32x4_t ab7654 = vmull_s16(a7654, b7654); /* 7777666655554444 */
4696*35ffd701SAndroid Build Coastguard Worker uint16x8x2_t r =
4697*35ffd701SAndroid Build Coastguard Worker vuzpq_u16(vreinterpretq_u16_s32(ab3210), vreinterpretq_u16_s32(ab7654));
4698*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(r.val[1]);
4699*35ffd701SAndroid Build Coastguard Worker }
4700*35ffd701SAndroid Build Coastguard Worker
4701*35ffd701SAndroid Build Coastguard Worker // Multiply the packed unsigned 16-bit integers in a and b, producing
4702*35ffd701SAndroid Build Coastguard Worker // intermediate 32-bit integers, and store the high 16 bits of the intermediate
4703*35ffd701SAndroid Build Coastguard Worker // integers in dst.
4704*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_epu16
_mm_mulhi_epu16(__m128i a,__m128i b)4705*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b)
4706*35ffd701SAndroid Build Coastguard Worker {
4707*35ffd701SAndroid Build Coastguard Worker uint16x4_t a3210 = vget_low_u16(vreinterpretq_u16_m128i(a));
4708*35ffd701SAndroid Build Coastguard Worker uint16x4_t b3210 = vget_low_u16(vreinterpretq_u16_m128i(b));
4709*35ffd701SAndroid Build Coastguard Worker uint32x4_t ab3210 = vmull_u16(a3210, b3210);
4710*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4711*35ffd701SAndroid Build Coastguard Worker uint32x4_t ab7654 =
4712*35ffd701SAndroid Build Coastguard Worker vmull_high_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b));
4713*35ffd701SAndroid Build Coastguard Worker uint16x8_t r = vuzp2q_u16(vreinterpretq_u16_u32(ab3210),
4714*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u16_u32(ab7654));
4715*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(r);
4716*35ffd701SAndroid Build Coastguard Worker #else
4717*35ffd701SAndroid Build Coastguard Worker uint16x4_t a7654 = vget_high_u16(vreinterpretq_u16_m128i(a));
4718*35ffd701SAndroid Build Coastguard Worker uint16x4_t b7654 = vget_high_u16(vreinterpretq_u16_m128i(b));
4719*35ffd701SAndroid Build Coastguard Worker uint32x4_t ab7654 = vmull_u16(a7654, b7654);
4720*35ffd701SAndroid Build Coastguard Worker uint16x8x2_t r =
4721*35ffd701SAndroid Build Coastguard Worker vuzpq_u16(vreinterpretq_u16_u32(ab3210), vreinterpretq_u16_u32(ab7654));
4722*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(r.val[1]);
4723*35ffd701SAndroid Build Coastguard Worker #endif
4724*35ffd701SAndroid Build Coastguard Worker }
4725*35ffd701SAndroid Build Coastguard Worker
4726*35ffd701SAndroid Build Coastguard Worker // Multiplies the 8 signed or unsigned 16-bit integers from a by the 8 signed or
4727*35ffd701SAndroid Build Coastguard Worker // unsigned 16-bit integers from b.
4728*35ffd701SAndroid Build Coastguard Worker //
4729*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 * b0)[15:0]
4730*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 * b1)[15:0]
4731*35ffd701SAndroid Build Coastguard Worker // ...
4732*35ffd701SAndroid Build Coastguard Worker // r7 := (a7 * b7)[15:0]
4733*35ffd701SAndroid Build Coastguard Worker //
4734*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/9ks1472s(v=vs.100).aspx
_mm_mullo_epi16(__m128i a,__m128i b)4735*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b)
4736*35ffd701SAndroid Build Coastguard Worker {
4737*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
4738*35ffd701SAndroid Build Coastguard Worker vmulq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
4739*35ffd701SAndroid Build Coastguard Worker }
4740*35ffd701SAndroid Build Coastguard Worker
4741*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise OR of packed double-precision (64-bit) floating-point
4742*35ffd701SAndroid Build Coastguard Worker // elements in a and b, and store the results in dst.
4743*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_or_pd
_mm_or_pd(__m128d a,__m128d b)4744*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_or_pd(__m128d a, __m128d b)
4745*35ffd701SAndroid Build Coastguard Worker {
4746*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(
4747*35ffd701SAndroid Build Coastguard Worker vorrq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b)));
4748*35ffd701SAndroid Build Coastguard Worker }
4749*35ffd701SAndroid Build Coastguard Worker
4750*35ffd701SAndroid Build Coastguard Worker // Computes the bitwise OR of the 128-bit value in a and the 128-bit value in b.
4751*35ffd701SAndroid Build Coastguard Worker //
4752*35ffd701SAndroid Build Coastguard Worker // r := a | b
4753*35ffd701SAndroid Build Coastguard Worker //
4754*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/ew8ty0db(v=vs.100).aspx
_mm_or_si128(__m128i a,__m128i b)4755*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_or_si128(__m128i a, __m128i b)
4756*35ffd701SAndroid Build Coastguard Worker {
4757*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
4758*35ffd701SAndroid Build Coastguard Worker vorrq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
4759*35ffd701SAndroid Build Coastguard Worker }
4760*35ffd701SAndroid Build Coastguard Worker
4761*35ffd701SAndroid Build Coastguard Worker // Packs the 16 signed 16-bit integers from a and b into 8-bit integers and
4762*35ffd701SAndroid Build Coastguard Worker // saturates.
4763*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/k4y4f7w5%28v=vs.90%29.aspx
_mm_packs_epi16(__m128i a,__m128i b)4764*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_packs_epi16(__m128i a, __m128i b)
4765*35ffd701SAndroid Build Coastguard Worker {
4766*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
4767*35ffd701SAndroid Build Coastguard Worker vcombine_s8(vqmovn_s16(vreinterpretq_s16_m128i(a)),
4768*35ffd701SAndroid Build Coastguard Worker vqmovn_s16(vreinterpretq_s16_m128i(b))));
4769*35ffd701SAndroid Build Coastguard Worker }
4770*35ffd701SAndroid Build Coastguard Worker
4771*35ffd701SAndroid Build Coastguard Worker // Packs the 8 signed 32-bit integers from a and b into signed 16-bit integers
4772*35ffd701SAndroid Build Coastguard Worker // and saturates.
4773*35ffd701SAndroid Build Coastguard Worker //
4774*35ffd701SAndroid Build Coastguard Worker // r0 := SignedSaturate(a0)
4775*35ffd701SAndroid Build Coastguard Worker // r1 := SignedSaturate(a1)
4776*35ffd701SAndroid Build Coastguard Worker // r2 := SignedSaturate(a2)
4777*35ffd701SAndroid Build Coastguard Worker // r3 := SignedSaturate(a3)
4778*35ffd701SAndroid Build Coastguard Worker // r4 := SignedSaturate(b0)
4779*35ffd701SAndroid Build Coastguard Worker // r5 := SignedSaturate(b1)
4780*35ffd701SAndroid Build Coastguard Worker // r6 := SignedSaturate(b2)
4781*35ffd701SAndroid Build Coastguard Worker // r7 := SignedSaturate(b3)
4782*35ffd701SAndroid Build Coastguard Worker //
4783*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/393t56f9%28v=vs.90%29.aspx
_mm_packs_epi32(__m128i a,__m128i b)4784*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_packs_epi32(__m128i a, __m128i b)
4785*35ffd701SAndroid Build Coastguard Worker {
4786*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
4787*35ffd701SAndroid Build Coastguard Worker vcombine_s16(vqmovn_s32(vreinterpretq_s32_m128i(a)),
4788*35ffd701SAndroid Build Coastguard Worker vqmovn_s32(vreinterpretq_s32_m128i(b))));
4789*35ffd701SAndroid Build Coastguard Worker }
4790*35ffd701SAndroid Build Coastguard Worker
4791*35ffd701SAndroid Build Coastguard Worker // Packs the 16 signed 16 - bit integers from a and b into 8 - bit unsigned
4792*35ffd701SAndroid Build Coastguard Worker // integers and saturates.
4793*35ffd701SAndroid Build Coastguard Worker //
4794*35ffd701SAndroid Build Coastguard Worker // r0 := UnsignedSaturate(a0)
4795*35ffd701SAndroid Build Coastguard Worker // r1 := UnsignedSaturate(a1)
4796*35ffd701SAndroid Build Coastguard Worker // ...
4797*35ffd701SAndroid Build Coastguard Worker // r7 := UnsignedSaturate(a7)
4798*35ffd701SAndroid Build Coastguard Worker // r8 := UnsignedSaturate(b0)
4799*35ffd701SAndroid Build Coastguard Worker // r9 := UnsignedSaturate(b1)
4800*35ffd701SAndroid Build Coastguard Worker // ...
4801*35ffd701SAndroid Build Coastguard Worker // r15 := UnsignedSaturate(b7)
4802*35ffd701SAndroid Build Coastguard Worker //
4803*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/07ad1wx4(v=vs.100).aspx
_mm_packus_epi16(const __m128i a,const __m128i b)4804*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b)
4805*35ffd701SAndroid Build Coastguard Worker {
4806*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
4807*35ffd701SAndroid Build Coastguard Worker vcombine_u8(vqmovun_s16(vreinterpretq_s16_m128i(a)),
4808*35ffd701SAndroid Build Coastguard Worker vqmovun_s16(vreinterpretq_s16_m128i(b))));
4809*35ffd701SAndroid Build Coastguard Worker }
4810*35ffd701SAndroid Build Coastguard Worker
4811*35ffd701SAndroid Build Coastguard Worker // Pause the processor. This is typically used in spin-wait loops and depending
4812*35ffd701SAndroid Build Coastguard Worker // on the x86 processor typical values are in the 40-100 cycle range. The
4813*35ffd701SAndroid Build Coastguard Worker // 'yield' instruction isn't a good fit beacuse it's effectively a nop on most
4814*35ffd701SAndroid Build Coastguard Worker // Arm cores. Experience with several databases has shown has shown an 'isb' is
4815*35ffd701SAndroid Build Coastguard Worker // a reasonable approximation.
_mm_pause()4816*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_pause()
4817*35ffd701SAndroid Build Coastguard Worker {
4818*35ffd701SAndroid Build Coastguard Worker __asm__ __volatile__("isb\n");
4819*35ffd701SAndroid Build Coastguard Worker }
4820*35ffd701SAndroid Build Coastguard Worker
4821*35ffd701SAndroid Build Coastguard Worker // Compute the absolute differences of packed unsigned 8-bit integers in a and
4822*35ffd701SAndroid Build Coastguard Worker // b, then horizontally sum each consecutive 8 differences to produce two
4823*35ffd701SAndroid Build Coastguard Worker // unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low
4824*35ffd701SAndroid Build Coastguard Worker // 16 bits of 64-bit elements in dst.
4825*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_epu8
_mm_sad_epu8(__m128i a,__m128i b)4826*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b)
4827*35ffd701SAndroid Build Coastguard Worker {
4828*35ffd701SAndroid Build Coastguard Worker uint16x8_t t = vpaddlq_u8(vabdq_u8((uint8x16_t) a, (uint8x16_t) b));
4829*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(vpaddlq_u32(vpaddlq_u16(t)));
4830*35ffd701SAndroid Build Coastguard Worker }
4831*35ffd701SAndroid Build Coastguard Worker
4832*35ffd701SAndroid Build Coastguard Worker // Sets the 8 signed 16-bit integer values.
4833*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-au/library/3e0fek84(v=vs.90).aspx
_mm_set_epi16(short i7,short i6,short i5,short i4,short i3,short i2,short i1,short i0)4834*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set_epi16(short i7,
4835*35ffd701SAndroid Build Coastguard Worker short i6,
4836*35ffd701SAndroid Build Coastguard Worker short i5,
4837*35ffd701SAndroid Build Coastguard Worker short i4,
4838*35ffd701SAndroid Build Coastguard Worker short i3,
4839*35ffd701SAndroid Build Coastguard Worker short i2,
4840*35ffd701SAndroid Build Coastguard Worker short i1,
4841*35ffd701SAndroid Build Coastguard Worker short i0)
4842*35ffd701SAndroid Build Coastguard Worker {
4843*35ffd701SAndroid Build Coastguard Worker int16_t ALIGN_STRUCT(16) data[8] = {i0, i1, i2, i3, i4, i5, i6, i7};
4844*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vld1q_s16(data));
4845*35ffd701SAndroid Build Coastguard Worker }
4846*35ffd701SAndroid Build Coastguard Worker
4847*35ffd701SAndroid Build Coastguard Worker // Sets the 4 signed 32-bit integer values.
4848*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx
_mm_set_epi32(int i3,int i2,int i1,int i0)4849*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0)
4850*35ffd701SAndroid Build Coastguard Worker {
4851*35ffd701SAndroid Build Coastguard Worker int32_t ALIGN_STRUCT(16) data[4] = {i0, i1, i2, i3};
4852*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vld1q_s32(data));
4853*35ffd701SAndroid Build Coastguard Worker }
4854*35ffd701SAndroid Build Coastguard Worker
4855*35ffd701SAndroid Build Coastguard Worker // Returns the __m128i structure with its two 64-bit integer values
4856*35ffd701SAndroid Build Coastguard Worker // initialized to the values of the two 64-bit integers passed in.
4857*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx
_mm_set_epi64(__m64 i1,__m64 i2)4858*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set_epi64(__m64 i1, __m64 i2)
4859*35ffd701SAndroid Build Coastguard Worker {
4860*35ffd701SAndroid Build Coastguard Worker return _mm_set_epi64x((int64_t) i1, (int64_t) i2);
4861*35ffd701SAndroid Build Coastguard Worker }
4862*35ffd701SAndroid Build Coastguard Worker
4863*35ffd701SAndroid Build Coastguard Worker // Returns the __m128i structure with its two 64-bit integer values
4864*35ffd701SAndroid Build Coastguard Worker // initialized to the values of the two 64-bit integers passed in.
4865*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx
_mm_set_epi64x(int64_t i1,int64_t i2)4866*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set_epi64x(int64_t i1, int64_t i2)
4867*35ffd701SAndroid Build Coastguard Worker {
4868*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(
4869*35ffd701SAndroid Build Coastguard Worker vcombine_s64(vcreate_s64(i2), vcreate_s64(i1)));
4870*35ffd701SAndroid Build Coastguard Worker }
4871*35ffd701SAndroid Build Coastguard Worker
4872*35ffd701SAndroid Build Coastguard Worker // Sets the 16 signed 8-bit integer values.
4873*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/x0cx8zd3(v=vs.90).aspx
_mm_set_epi8(signed char b15,signed char b14,signed char b13,signed char b12,signed char b11,signed char b10,signed char b9,signed char b8,signed char b7,signed char b6,signed char b5,signed char b4,signed char b3,signed char b2,signed char b1,signed char b0)4874*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set_epi8(signed char b15,
4875*35ffd701SAndroid Build Coastguard Worker signed char b14,
4876*35ffd701SAndroid Build Coastguard Worker signed char b13,
4877*35ffd701SAndroid Build Coastguard Worker signed char b12,
4878*35ffd701SAndroid Build Coastguard Worker signed char b11,
4879*35ffd701SAndroid Build Coastguard Worker signed char b10,
4880*35ffd701SAndroid Build Coastguard Worker signed char b9,
4881*35ffd701SAndroid Build Coastguard Worker signed char b8,
4882*35ffd701SAndroid Build Coastguard Worker signed char b7,
4883*35ffd701SAndroid Build Coastguard Worker signed char b6,
4884*35ffd701SAndroid Build Coastguard Worker signed char b5,
4885*35ffd701SAndroid Build Coastguard Worker signed char b4,
4886*35ffd701SAndroid Build Coastguard Worker signed char b3,
4887*35ffd701SAndroid Build Coastguard Worker signed char b2,
4888*35ffd701SAndroid Build Coastguard Worker signed char b1,
4889*35ffd701SAndroid Build Coastguard Worker signed char b0)
4890*35ffd701SAndroid Build Coastguard Worker {
4891*35ffd701SAndroid Build Coastguard Worker int8_t ALIGN_STRUCT(16)
4892*35ffd701SAndroid Build Coastguard Worker data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3,
4893*35ffd701SAndroid Build Coastguard Worker (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7,
4894*35ffd701SAndroid Build Coastguard Worker (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11,
4895*35ffd701SAndroid Build Coastguard Worker (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15};
4896*35ffd701SAndroid Build Coastguard Worker return (__m128i) vld1q_s8(data);
4897*35ffd701SAndroid Build Coastguard Worker }
4898*35ffd701SAndroid Build Coastguard Worker
4899*35ffd701SAndroid Build Coastguard Worker // Set packed double-precision (64-bit) floating-point elements in dst with the
4900*35ffd701SAndroid Build Coastguard Worker // supplied values.
4901*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd
_mm_set_pd(double e1,double e0)4902*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_set_pd(double e1, double e0)
4903*35ffd701SAndroid Build Coastguard Worker {
4904*35ffd701SAndroid Build Coastguard Worker double ALIGN_STRUCT(16) data[2] = {e0, e1};
4905*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4906*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vld1q_f64((float64_t *) data));
4907*35ffd701SAndroid Build Coastguard Worker #else
4908*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) data));
4909*35ffd701SAndroid Build Coastguard Worker #endif
4910*35ffd701SAndroid Build Coastguard Worker }
4911*35ffd701SAndroid Build Coastguard Worker
4912*35ffd701SAndroid Build Coastguard Worker // Broadcast double-precision (64-bit) floating-point value a to all elements of
4913*35ffd701SAndroid Build Coastguard Worker // dst.
4914*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd1
4915*35ffd701SAndroid Build Coastguard Worker #define _mm_set_pd1 _mm_set1_pd
4916*35ffd701SAndroid Build Coastguard Worker
4917*35ffd701SAndroid Build Coastguard Worker // Copy double-precision (64-bit) floating-point element a to the lower element
4918*35ffd701SAndroid Build Coastguard Worker // of dst, and zero the upper element.
4919*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_sd
_mm_set_sd(double a)4920*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_set_sd(double a)
4921*35ffd701SAndroid Build Coastguard Worker {
4922*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(0, a);
4923*35ffd701SAndroid Build Coastguard Worker }
4924*35ffd701SAndroid Build Coastguard Worker
4925*35ffd701SAndroid Build Coastguard Worker // Sets the 8 signed 16-bit integer values to w.
4926*35ffd701SAndroid Build Coastguard Worker //
4927*35ffd701SAndroid Build Coastguard Worker // r0 := w
4928*35ffd701SAndroid Build Coastguard Worker // r1 := w
4929*35ffd701SAndroid Build Coastguard Worker // ...
4930*35ffd701SAndroid Build Coastguard Worker // r7 := w
4931*35ffd701SAndroid Build Coastguard Worker //
4932*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/k0ya3x0e(v=vs.90).aspx
_mm_set1_epi16(short w)4933*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set1_epi16(short w)
4934*35ffd701SAndroid Build Coastguard Worker {
4935*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vdupq_n_s16(w));
4936*35ffd701SAndroid Build Coastguard Worker }
4937*35ffd701SAndroid Build Coastguard Worker
4938*35ffd701SAndroid Build Coastguard Worker // Sets the 4 signed 32-bit integer values to i.
4939*35ffd701SAndroid Build Coastguard Worker //
4940*35ffd701SAndroid Build Coastguard Worker // r0 := i
4941*35ffd701SAndroid Build Coastguard Worker // r1 := i
4942*35ffd701SAndroid Build Coastguard Worker // r2 := i
4943*35ffd701SAndroid Build Coastguard Worker // r3 := I
4944*35ffd701SAndroid Build Coastguard Worker //
4945*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/h4xscxat(v=vs.100).aspx
_mm_set1_epi32(int _i)4946*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set1_epi32(int _i)
4947*35ffd701SAndroid Build Coastguard Worker {
4948*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vdupq_n_s32(_i));
4949*35ffd701SAndroid Build Coastguard Worker }
4950*35ffd701SAndroid Build Coastguard Worker
4951*35ffd701SAndroid Build Coastguard Worker // Sets the 2 signed 64-bit integer values to i.
4952*35ffd701SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/whtfzhzk(v=vs.100)
_mm_set1_epi64(__m64 _i)4953*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set1_epi64(__m64 _i)
4954*35ffd701SAndroid Build Coastguard Worker {
4955*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vdupq_n_s64((int64_t) _i));
4956*35ffd701SAndroid Build Coastguard Worker }
4957*35ffd701SAndroid Build Coastguard Worker
4958*35ffd701SAndroid Build Coastguard Worker // Sets the 2 signed 64-bit integer values to i.
4959*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_epi64x
_mm_set1_epi64x(int64_t _i)4960*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set1_epi64x(int64_t _i)
4961*35ffd701SAndroid Build Coastguard Worker {
4962*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vdupq_n_s64(_i));
4963*35ffd701SAndroid Build Coastguard Worker }
4964*35ffd701SAndroid Build Coastguard Worker
4965*35ffd701SAndroid Build Coastguard Worker // Sets the 16 signed 8-bit integer values to b.
4966*35ffd701SAndroid Build Coastguard Worker //
4967*35ffd701SAndroid Build Coastguard Worker // r0 := b
4968*35ffd701SAndroid Build Coastguard Worker // r1 := b
4969*35ffd701SAndroid Build Coastguard Worker // ...
4970*35ffd701SAndroid Build Coastguard Worker // r15 := b
4971*35ffd701SAndroid Build Coastguard Worker //
4972*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/6e14xhyf(v=vs.100).aspx
_mm_set1_epi8(signed char w)4973*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_set1_epi8(signed char w)
4974*35ffd701SAndroid Build Coastguard Worker {
4975*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(vdupq_n_s8(w));
4976*35ffd701SAndroid Build Coastguard Worker }
4977*35ffd701SAndroid Build Coastguard Worker
4978*35ffd701SAndroid Build Coastguard Worker // Broadcast double-precision (64-bit) floating-point value a to all elements of
4979*35ffd701SAndroid Build Coastguard Worker // dst.
4980*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_pd
_mm_set1_pd(double d)4981*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_set1_pd(double d)
4982*35ffd701SAndroid Build Coastguard Worker {
4983*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
4984*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vdupq_n_f64(d));
4985*35ffd701SAndroid Build Coastguard Worker #else
4986*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(vdupq_n_s64(*(int64_t *) &d));
4987*35ffd701SAndroid Build Coastguard Worker #endif
4988*35ffd701SAndroid Build Coastguard Worker }
4989*35ffd701SAndroid Build Coastguard Worker
4990*35ffd701SAndroid Build Coastguard Worker // Sets the 8 signed 16-bit integer values in reverse order.
4991*35ffd701SAndroid Build Coastguard Worker //
4992*35ffd701SAndroid Build Coastguard Worker // Return Value
4993*35ffd701SAndroid Build Coastguard Worker // r0 := w0
4994*35ffd701SAndroid Build Coastguard Worker // r1 := w1
4995*35ffd701SAndroid Build Coastguard Worker // ...
4996*35ffd701SAndroid Build Coastguard Worker // r7 := w7
_mm_setr_epi16(short w0,short w1,short w2,short w3,short w4,short w5,short w6,short w7)4997*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_setr_epi16(short w0,
4998*35ffd701SAndroid Build Coastguard Worker short w1,
4999*35ffd701SAndroid Build Coastguard Worker short w2,
5000*35ffd701SAndroid Build Coastguard Worker short w3,
5001*35ffd701SAndroid Build Coastguard Worker short w4,
5002*35ffd701SAndroid Build Coastguard Worker short w5,
5003*35ffd701SAndroid Build Coastguard Worker short w6,
5004*35ffd701SAndroid Build Coastguard Worker short w7)
5005*35ffd701SAndroid Build Coastguard Worker {
5006*35ffd701SAndroid Build Coastguard Worker int16_t ALIGN_STRUCT(16) data[8] = {w0, w1, w2, w3, w4, w5, w6, w7};
5007*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vld1q_s16((int16_t *) data));
5008*35ffd701SAndroid Build Coastguard Worker }
5009*35ffd701SAndroid Build Coastguard Worker
5010*35ffd701SAndroid Build Coastguard Worker // Sets the 4 signed 32-bit integer values in reverse order
5011*35ffd701SAndroid Build Coastguard Worker // https://technet.microsoft.com/en-us/library/security/27yb3ee5(v=vs.90).aspx
_mm_setr_epi32(int i3,int i2,int i1,int i0)5012*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_setr_epi32(int i3, int i2, int i1, int i0)
5013*35ffd701SAndroid Build Coastguard Worker {
5014*35ffd701SAndroid Build Coastguard Worker int32_t ALIGN_STRUCT(16) data[4] = {i3, i2, i1, i0};
5015*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vld1q_s32(data));
5016*35ffd701SAndroid Build Coastguard Worker }
5017*35ffd701SAndroid Build Coastguard Worker
5018*35ffd701SAndroid Build Coastguard Worker // Set packed 64-bit integers in dst with the supplied values in reverse order.
5019*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_epi64
_mm_setr_epi64(__m64 e1,__m64 e0)5020*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_setr_epi64(__m64 e1, __m64 e0)
5021*35ffd701SAndroid Build Coastguard Worker {
5022*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vcombine_s64(e1, e0));
5023*35ffd701SAndroid Build Coastguard Worker }
5024*35ffd701SAndroid Build Coastguard Worker
5025*35ffd701SAndroid Build Coastguard Worker // Sets the 16 signed 8-bit integer values in reverse order.
5026*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/2khb9c7k(v=vs.90).aspx
_mm_setr_epi8(signed char b0,signed char b1,signed char b2,signed char b3,signed char b4,signed char b5,signed char b6,signed char b7,signed char b8,signed char b9,signed char b10,signed char b11,signed char b12,signed char b13,signed char b14,signed char b15)5027*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_setr_epi8(signed char b0,
5028*35ffd701SAndroid Build Coastguard Worker signed char b1,
5029*35ffd701SAndroid Build Coastguard Worker signed char b2,
5030*35ffd701SAndroid Build Coastguard Worker signed char b3,
5031*35ffd701SAndroid Build Coastguard Worker signed char b4,
5032*35ffd701SAndroid Build Coastguard Worker signed char b5,
5033*35ffd701SAndroid Build Coastguard Worker signed char b6,
5034*35ffd701SAndroid Build Coastguard Worker signed char b7,
5035*35ffd701SAndroid Build Coastguard Worker signed char b8,
5036*35ffd701SAndroid Build Coastguard Worker signed char b9,
5037*35ffd701SAndroid Build Coastguard Worker signed char b10,
5038*35ffd701SAndroid Build Coastguard Worker signed char b11,
5039*35ffd701SAndroid Build Coastguard Worker signed char b12,
5040*35ffd701SAndroid Build Coastguard Worker signed char b13,
5041*35ffd701SAndroid Build Coastguard Worker signed char b14,
5042*35ffd701SAndroid Build Coastguard Worker signed char b15)
5043*35ffd701SAndroid Build Coastguard Worker {
5044*35ffd701SAndroid Build Coastguard Worker int8_t ALIGN_STRUCT(16)
5045*35ffd701SAndroid Build Coastguard Worker data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3,
5046*35ffd701SAndroid Build Coastguard Worker (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7,
5047*35ffd701SAndroid Build Coastguard Worker (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11,
5048*35ffd701SAndroid Build Coastguard Worker (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15};
5049*35ffd701SAndroid Build Coastguard Worker return (__m128i) vld1q_s8(data);
5050*35ffd701SAndroid Build Coastguard Worker }
5051*35ffd701SAndroid Build Coastguard Worker
5052*35ffd701SAndroid Build Coastguard Worker // Set packed double-precision (64-bit) floating-point elements in dst with the
5053*35ffd701SAndroid Build Coastguard Worker // supplied values in reverse order.
5054*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_pd
_mm_setr_pd(double e1,double e0)5055*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_setr_pd(double e1, double e0)
5056*35ffd701SAndroid Build Coastguard Worker {
5057*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(e0, e1);
5058*35ffd701SAndroid Build Coastguard Worker }
5059*35ffd701SAndroid Build Coastguard Worker
5060*35ffd701SAndroid Build Coastguard Worker // Return vector of type __m128d with all elements set to zero.
5061*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setzero_pd
_mm_setzero_pd(void)5062*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_setzero_pd(void)
5063*35ffd701SAndroid Build Coastguard Worker {
5064*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5065*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vdupq_n_f64(0));
5066*35ffd701SAndroid Build Coastguard Worker #else
5067*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f32(vdupq_n_f32(0));
5068*35ffd701SAndroid Build Coastguard Worker #endif
5069*35ffd701SAndroid Build Coastguard Worker }
5070*35ffd701SAndroid Build Coastguard Worker
5071*35ffd701SAndroid Build Coastguard Worker // Sets the 128-bit value to zero
5072*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/ys7dw0kh(v=vs.100).aspx
_mm_setzero_si128(void)5073*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_setzero_si128(void)
5074*35ffd701SAndroid Build Coastguard Worker {
5075*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vdupq_n_s32(0));
5076*35ffd701SAndroid Build Coastguard Worker }
5077*35ffd701SAndroid Build Coastguard Worker
5078*35ffd701SAndroid Build Coastguard Worker // Shuffles the 4 signed or unsigned 32-bit integers in a as specified by imm.
5079*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/56f67xbk%28v=vs.90%29.aspx
5080*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i a,
5081*35ffd701SAndroid Build Coastguard Worker // __constrange(0,255) int imm)
5082*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_shufflevector)
5083*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_epi32(a, imm) \
5084*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5085*35ffd701SAndroid Build Coastguard Worker int32x4_t _input = vreinterpretq_s32_m128i(a); \
5086*35ffd701SAndroid Build Coastguard Worker int32x4_t _shuf = __builtin_shufflevector( \
5087*35ffd701SAndroid Build Coastguard Worker _input, _input, (imm) & (0x3), ((imm) >> 2) & 0x3, \
5088*35ffd701SAndroid Build Coastguard Worker ((imm) >> 4) & 0x3, ((imm) >> 6) & 0x3); \
5089*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s32(_shuf); \
5090*35ffd701SAndroid Build Coastguard Worker })
5091*35ffd701SAndroid Build Coastguard Worker #else // generic
5092*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_epi32(a, imm) \
5093*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5094*35ffd701SAndroid Build Coastguard Worker __m128i ret; \
5095*35ffd701SAndroid Build Coastguard Worker switch (imm) { \
5096*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(1, 0, 3, 2): \
5097*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_1032((a)); \
5098*35ffd701SAndroid Build Coastguard Worker break; \
5099*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 3, 0, 1): \
5100*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_2301((a)); \
5101*35ffd701SAndroid Build Coastguard Worker break; \
5102*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(0, 3, 2, 1): \
5103*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_0321((a)); \
5104*35ffd701SAndroid Build Coastguard Worker break; \
5105*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 1, 0, 3): \
5106*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_2103((a)); \
5107*35ffd701SAndroid Build Coastguard Worker break; \
5108*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(1, 0, 1, 0): \
5109*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_1010((a)); \
5110*35ffd701SAndroid Build Coastguard Worker break; \
5111*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(1, 0, 0, 1): \
5112*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_1001((a)); \
5113*35ffd701SAndroid Build Coastguard Worker break; \
5114*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(0, 1, 0, 1): \
5115*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_0101((a)); \
5116*35ffd701SAndroid Build Coastguard Worker break; \
5117*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 2, 1, 1): \
5118*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_2211((a)); \
5119*35ffd701SAndroid Build Coastguard Worker break; \
5120*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(0, 1, 2, 2): \
5121*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_0122((a)); \
5122*35ffd701SAndroid Build Coastguard Worker break; \
5123*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(3, 3, 3, 2): \
5124*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi_3332((a)); \
5125*35ffd701SAndroid Build Coastguard Worker break; \
5126*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(0, 0, 0, 0): \
5127*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi32_splat((a), 0); \
5128*35ffd701SAndroid Build Coastguard Worker break; \
5129*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(1, 1, 1, 1): \
5130*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi32_splat((a), 1); \
5131*35ffd701SAndroid Build Coastguard Worker break; \
5132*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(2, 2, 2, 2): \
5133*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi32_splat((a), 2); \
5134*35ffd701SAndroid Build Coastguard Worker break; \
5135*35ffd701SAndroid Build Coastguard Worker case _MM_SHUFFLE(3, 3, 3, 3): \
5136*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi32_splat((a), 3); \
5137*35ffd701SAndroid Build Coastguard Worker break; \
5138*35ffd701SAndroid Build Coastguard Worker default: \
5139*35ffd701SAndroid Build Coastguard Worker ret = _mm_shuffle_epi32_default((a), (imm)); \
5140*35ffd701SAndroid Build Coastguard Worker break; \
5141*35ffd701SAndroid Build Coastguard Worker } \
5142*35ffd701SAndroid Build Coastguard Worker ret; \
5143*35ffd701SAndroid Build Coastguard Worker })
5144*35ffd701SAndroid Build Coastguard Worker #endif
5145*35ffd701SAndroid Build Coastguard Worker
5146*35ffd701SAndroid Build Coastguard Worker // Shuffle double-precision (64-bit) floating-point elements using the control
5147*35ffd701SAndroid Build Coastguard Worker // in imm8, and store the results in dst.
5148*35ffd701SAndroid Build Coastguard Worker //
5149*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := (imm8[0] == 0) ? a[63:0] : a[127:64]
5150*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := (imm8[1] == 0) ? b[63:0] : b[127:64]
5151*35ffd701SAndroid Build Coastguard Worker //
5152*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pd
5153*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_shufflevector)
5154*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_pd(a, b, imm8) \
5155*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128d_s64(__builtin_shufflevector( \
5156*35ffd701SAndroid Build Coastguard Worker vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b), imm8 & 0x1, \
5157*35ffd701SAndroid Build Coastguard Worker ((imm8 & 0x2) >> 1) + 2))
5158*35ffd701SAndroid Build Coastguard Worker #else
5159*35ffd701SAndroid Build Coastguard Worker #define _mm_shuffle_pd(a, b, imm8) \
5160*35ffd701SAndroid Build Coastguard Worker _mm_castsi128_pd(_mm_set_epi64x( \
5161*35ffd701SAndroid Build Coastguard Worker vgetq_lane_s64(vreinterpretq_s64_m128d(b), (imm8 & 0x2) >> 1), \
5162*35ffd701SAndroid Build Coastguard Worker vgetq_lane_s64(vreinterpretq_s64_m128d(a), imm8 & 0x1)))
5163*35ffd701SAndroid Build Coastguard Worker #endif
5164*35ffd701SAndroid Build Coastguard Worker
5165*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i a,
5166*35ffd701SAndroid Build Coastguard Worker // __constrange(0,255) int imm)
5167*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_shufflevector)
5168*35ffd701SAndroid Build Coastguard Worker #define _mm_shufflehi_epi16(a, imm) \
5169*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5170*35ffd701SAndroid Build Coastguard Worker int16x8_t _input = vreinterpretq_s16_m128i(a); \
5171*35ffd701SAndroid Build Coastguard Worker int16x8_t _shuf = __builtin_shufflevector( \
5172*35ffd701SAndroid Build Coastguard Worker _input, _input, 0, 1, 2, 3, ((imm) & (0x3)) + 4, \
5173*35ffd701SAndroid Build Coastguard Worker (((imm) >> 2) & 0x3) + 4, (((imm) >> 4) & 0x3) + 4, \
5174*35ffd701SAndroid Build Coastguard Worker (((imm) >> 6) & 0x3) + 4); \
5175*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s16(_shuf); \
5176*35ffd701SAndroid Build Coastguard Worker })
5177*35ffd701SAndroid Build Coastguard Worker #else // generic
5178*35ffd701SAndroid Build Coastguard Worker #define _mm_shufflehi_epi16(a, imm) _mm_shufflehi_epi16_function((a), (imm))
5179*35ffd701SAndroid Build Coastguard Worker #endif
5180*35ffd701SAndroid Build Coastguard Worker
5181*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i a,
5182*35ffd701SAndroid Build Coastguard Worker // __constrange(0,255) int imm)
5183*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_shufflevector)
5184*35ffd701SAndroid Build Coastguard Worker #define _mm_shufflelo_epi16(a, imm) \
5185*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5186*35ffd701SAndroid Build Coastguard Worker int16x8_t _input = vreinterpretq_s16_m128i(a); \
5187*35ffd701SAndroid Build Coastguard Worker int16x8_t _shuf = __builtin_shufflevector( \
5188*35ffd701SAndroid Build Coastguard Worker _input, _input, ((imm) & (0x3)), (((imm) >> 2) & 0x3), \
5189*35ffd701SAndroid Build Coastguard Worker (((imm) >> 4) & 0x3), (((imm) >> 6) & 0x3), 4, 5, 6, 7); \
5190*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s16(_shuf); \
5191*35ffd701SAndroid Build Coastguard Worker })
5192*35ffd701SAndroid Build Coastguard Worker #else // generic
5193*35ffd701SAndroid Build Coastguard Worker #define _mm_shufflelo_epi16(a, imm) _mm_shufflelo_epi16_function((a), (imm))
5194*35ffd701SAndroid Build Coastguard Worker #endif
5195*35ffd701SAndroid Build Coastguard Worker
5196*35ffd701SAndroid Build Coastguard Worker // Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while
5197*35ffd701SAndroid Build Coastguard Worker // shifting in zeros.
5198*35ffd701SAndroid Build Coastguard Worker //
5199*35ffd701SAndroid Build Coastguard Worker // r0 := a0 << count
5200*35ffd701SAndroid Build Coastguard Worker // r1 := a1 << count
5201*35ffd701SAndroid Build Coastguard Worker // ...
5202*35ffd701SAndroid Build Coastguard Worker // r7 := a7 << count
5203*35ffd701SAndroid Build Coastguard Worker //
5204*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/c79w388h(v%3dvs.90).aspx
_mm_sll_epi16(__m128i a,__m128i count)5205*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sll_epi16(__m128i a, __m128i count)
5206*35ffd701SAndroid Build Coastguard Worker {
5207*35ffd701SAndroid Build Coastguard Worker uint64_t c = vreinterpretq_nth_u64_m128i(count, 0);
5208*35ffd701SAndroid Build Coastguard Worker if (unlikely(c > 15))
5209*35ffd701SAndroid Build Coastguard Worker return _mm_setzero_si128();
5210*35ffd701SAndroid Build Coastguard Worker
5211*35ffd701SAndroid Build Coastguard Worker int16x8_t vc = vdupq_n_s16((int16_t) c);
5212*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vshlq_s16(vreinterpretq_s16_m128i(a), vc));
5213*35ffd701SAndroid Build Coastguard Worker }
5214*35ffd701SAndroid Build Coastguard Worker
5215*35ffd701SAndroid Build Coastguard Worker // Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while
5216*35ffd701SAndroid Build Coastguard Worker // shifting in zeros.
5217*35ffd701SAndroid Build Coastguard Worker //
5218*35ffd701SAndroid Build Coastguard Worker // r0 := a0 << count
5219*35ffd701SAndroid Build Coastguard Worker // r1 := a1 << count
5220*35ffd701SAndroid Build Coastguard Worker // r2 := a2 << count
5221*35ffd701SAndroid Build Coastguard Worker // r3 := a3 << count
5222*35ffd701SAndroid Build Coastguard Worker //
5223*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/6fe5a6s9(v%3dvs.90).aspx
_mm_sll_epi32(__m128i a,__m128i count)5224*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sll_epi32(__m128i a, __m128i count)
5225*35ffd701SAndroid Build Coastguard Worker {
5226*35ffd701SAndroid Build Coastguard Worker uint64_t c = vreinterpretq_nth_u64_m128i(count, 0);
5227*35ffd701SAndroid Build Coastguard Worker if (unlikely(c > 31))
5228*35ffd701SAndroid Build Coastguard Worker return _mm_setzero_si128();
5229*35ffd701SAndroid Build Coastguard Worker
5230*35ffd701SAndroid Build Coastguard Worker int32x4_t vc = vdupq_n_s32((int32_t) c);
5231*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vshlq_s32(vreinterpretq_s32_m128i(a), vc));
5232*35ffd701SAndroid Build Coastguard Worker }
5233*35ffd701SAndroid Build Coastguard Worker
5234*35ffd701SAndroid Build Coastguard Worker // Shifts the 2 signed or unsigned 64-bit integers in a left by count bits while
5235*35ffd701SAndroid Build Coastguard Worker // shifting in zeros.
5236*35ffd701SAndroid Build Coastguard Worker //
5237*35ffd701SAndroid Build Coastguard Worker // r0 := a0 << count
5238*35ffd701SAndroid Build Coastguard Worker // r1 := a1 << count
5239*35ffd701SAndroid Build Coastguard Worker //
5240*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/6ta9dffd(v%3dvs.90).aspx
_mm_sll_epi64(__m128i a,__m128i count)5241*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sll_epi64(__m128i a, __m128i count)
5242*35ffd701SAndroid Build Coastguard Worker {
5243*35ffd701SAndroid Build Coastguard Worker uint64_t c = vreinterpretq_nth_u64_m128i(count, 0);
5244*35ffd701SAndroid Build Coastguard Worker if (unlikely(c > 63))
5245*35ffd701SAndroid Build Coastguard Worker return _mm_setzero_si128();
5246*35ffd701SAndroid Build Coastguard Worker
5247*35ffd701SAndroid Build Coastguard Worker int64x2_t vc = vdupq_n_s64((int64_t) c);
5248*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vshlq_s64(vreinterpretq_s64_m128i(a), vc));
5249*35ffd701SAndroid Build Coastguard Worker }
5250*35ffd701SAndroid Build Coastguard Worker
5251*35ffd701SAndroid Build Coastguard Worker // Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while
5252*35ffd701SAndroid Build Coastguard Worker // shifting in zeros.
5253*35ffd701SAndroid Build Coastguard Worker //
5254*35ffd701SAndroid Build Coastguard Worker // r0 := a0 << count
5255*35ffd701SAndroid Build Coastguard Worker // r1 := a1 << count
5256*35ffd701SAndroid Build Coastguard Worker // ...
5257*35ffd701SAndroid Build Coastguard Worker // r7 := a7 << count
5258*35ffd701SAndroid Build Coastguard Worker //
5259*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/es73bcsy(v=vs.90).aspx
5260*35ffd701SAndroid Build Coastguard Worker #define _mm_slli_epi16(a, imm) \
5261*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5262*35ffd701SAndroid Build Coastguard Worker __m128i ret; \
5263*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm)) <= 0) { \
5264*35ffd701SAndroid Build Coastguard Worker ret = a; \
5265*35ffd701SAndroid Build Coastguard Worker } \
5266*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) > 15)) { \
5267*35ffd701SAndroid Build Coastguard Worker ret = _mm_setzero_si128(); \
5268*35ffd701SAndroid Build Coastguard Worker } else { \
5269*35ffd701SAndroid Build Coastguard Worker ret = vreinterpretq_m128i_s16( \
5270*35ffd701SAndroid Build Coastguard Worker vshlq_n_s16(vreinterpretq_s16_m128i(a), (imm))); \
5271*35ffd701SAndroid Build Coastguard Worker } \
5272*35ffd701SAndroid Build Coastguard Worker ret; \
5273*35ffd701SAndroid Build Coastguard Worker })
5274*35ffd701SAndroid Build Coastguard Worker
5275*35ffd701SAndroid Build Coastguard Worker // Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while
5276*35ffd701SAndroid Build Coastguard Worker // shifting in zeros. :
5277*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/z2k3bbtb%28v=vs.90%29.aspx
5278*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, __constrange(0,255) int imm)
_mm_slli_epi32(__m128i a,int imm)5279*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, int imm)
5280*35ffd701SAndroid Build Coastguard Worker {
5281*35ffd701SAndroid Build Coastguard Worker if (unlikely(imm <= 0)) /* TODO: add constant range macro: [0, 255] */
5282*35ffd701SAndroid Build Coastguard Worker return a;
5283*35ffd701SAndroid Build Coastguard Worker if (unlikely(imm > 31))
5284*35ffd701SAndroid Build Coastguard Worker return _mm_setzero_si128();
5285*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
5286*35ffd701SAndroid Build Coastguard Worker vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(imm)));
5287*35ffd701SAndroid Build Coastguard Worker }
5288*35ffd701SAndroid Build Coastguard Worker
5289*35ffd701SAndroid Build Coastguard Worker // Shift packed 64-bit integers in a left by imm8 while shifting in zeros, and
5290*35ffd701SAndroid Build Coastguard Worker // store the results in dst.
_mm_slli_epi64(__m128i a,int imm)5291*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm)
5292*35ffd701SAndroid Build Coastguard Worker {
5293*35ffd701SAndroid Build Coastguard Worker if (unlikely(imm <= 0)) /* TODO: add constant range macro: [0, 255] */
5294*35ffd701SAndroid Build Coastguard Worker return a;
5295*35ffd701SAndroid Build Coastguard Worker if (unlikely(imm > 63))
5296*35ffd701SAndroid Build Coastguard Worker return _mm_setzero_si128();
5297*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(
5298*35ffd701SAndroid Build Coastguard Worker vshlq_s64(vreinterpretq_s64_m128i(a), vdupq_n_s64(imm)));
5299*35ffd701SAndroid Build Coastguard Worker }
5300*35ffd701SAndroid Build Coastguard Worker
5301*35ffd701SAndroid Build Coastguard Worker // Shifts the 128-bit value in a left by imm bytes while shifting in zeros. imm
5302*35ffd701SAndroid Build Coastguard Worker // must be an immediate.
5303*35ffd701SAndroid Build Coastguard Worker //
5304*35ffd701SAndroid Build Coastguard Worker // r := a << (imm * 8)
5305*35ffd701SAndroid Build Coastguard Worker //
5306*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/34d3k2kt(v=vs.100).aspx
5307*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_slli_si128(__m128i a, __constrange(0,255) int imm)
5308*35ffd701SAndroid Build Coastguard Worker #define _mm_slli_si128(a, imm) \
5309*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5310*35ffd701SAndroid Build Coastguard Worker __m128i ret; \
5311*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) <= 0)) { \
5312*35ffd701SAndroid Build Coastguard Worker ret = a; \
5313*35ffd701SAndroid Build Coastguard Worker } \
5314*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) > 15)) { \
5315*35ffd701SAndroid Build Coastguard Worker ret = _mm_setzero_si128(); \
5316*35ffd701SAndroid Build Coastguard Worker } else { \
5317*35ffd701SAndroid Build Coastguard Worker ret = vreinterpretq_m128i_s8(vextq_s8( \
5318*35ffd701SAndroid Build Coastguard Worker vdupq_n_s8(0), vreinterpretq_s8_m128i(a), 16 - (imm))); \
5319*35ffd701SAndroid Build Coastguard Worker } \
5320*35ffd701SAndroid Build Coastguard Worker ret; \
5321*35ffd701SAndroid Build Coastguard Worker })
5322*35ffd701SAndroid Build Coastguard Worker
5323*35ffd701SAndroid Build Coastguard Worker // Compute the square root of packed double-precision (64-bit) floating-point
5324*35ffd701SAndroid Build Coastguard Worker // elements in a, and store the results in dst.
5325*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_pd
_mm_sqrt_pd(__m128d a)5326*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_sqrt_pd(__m128d a)
5327*35ffd701SAndroid Build Coastguard Worker {
5328*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5329*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vsqrtq_f64(vreinterpretq_f64_m128d(a)));
5330*35ffd701SAndroid Build Coastguard Worker #else
5331*35ffd701SAndroid Build Coastguard Worker double a0 = sqrt(((double *) &a)[0]);
5332*35ffd701SAndroid Build Coastguard Worker double a1 = sqrt(((double *) &a)[1]);
5333*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(a1, a0);
5334*35ffd701SAndroid Build Coastguard Worker #endif
5335*35ffd701SAndroid Build Coastguard Worker }
5336*35ffd701SAndroid Build Coastguard Worker
5337*35ffd701SAndroid Build Coastguard Worker // Compute the square root of the lower double-precision (64-bit) floating-point
5338*35ffd701SAndroid Build Coastguard Worker // element in b, store the result in the lower element of dst, and copy the
5339*35ffd701SAndroid Build Coastguard Worker // upper element from a to the upper element of dst.
5340*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_sd
_mm_sqrt_sd(__m128d a,__m128d b)5341*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_sqrt_sd(__m128d a, __m128d b)
5342*35ffd701SAndroid Build Coastguard Worker {
5343*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5344*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_sqrt_pd(b));
5345*35ffd701SAndroid Build Coastguard Worker #else
5346*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(((double *) &a)[1], sqrt(((double *) &b)[0]));
5347*35ffd701SAndroid Build Coastguard Worker #endif
5348*35ffd701SAndroid Build Coastguard Worker }
5349*35ffd701SAndroid Build Coastguard Worker
5350*35ffd701SAndroid Build Coastguard Worker // Shifts the 8 signed 16-bit integers in a right by count bits while shifting
5351*35ffd701SAndroid Build Coastguard Worker // in the sign bit.
5352*35ffd701SAndroid Build Coastguard Worker //
5353*35ffd701SAndroid Build Coastguard Worker // r0 := a0 >> count
5354*35ffd701SAndroid Build Coastguard Worker // r1 := a1 >> count
5355*35ffd701SAndroid Build Coastguard Worker // ...
5356*35ffd701SAndroid Build Coastguard Worker // r7 := a7 >> count
5357*35ffd701SAndroid Build Coastguard Worker //
5358*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/3c9997dk(v%3dvs.90).aspx
_mm_sra_epi16(__m128i a,__m128i count)5359*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count)
5360*35ffd701SAndroid Build Coastguard Worker {
5361*35ffd701SAndroid Build Coastguard Worker int64_t c = (int64_t) vget_low_s64((int64x2_t) count);
5362*35ffd701SAndroid Build Coastguard Worker if (unlikely(c > 15))
5363*35ffd701SAndroid Build Coastguard Worker return _mm_cmplt_epi16(a, _mm_setzero_si128());
5364*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vshlq_s16((int16x8_t) a, vdupq_n_s16(-c)));
5365*35ffd701SAndroid Build Coastguard Worker }
5366*35ffd701SAndroid Build Coastguard Worker
5367*35ffd701SAndroid Build Coastguard Worker // Shifts the 4 signed 32-bit integers in a right by count bits while shifting
5368*35ffd701SAndroid Build Coastguard Worker // in the sign bit.
5369*35ffd701SAndroid Build Coastguard Worker //
5370*35ffd701SAndroid Build Coastguard Worker // r0 := a0 >> count
5371*35ffd701SAndroid Build Coastguard Worker // r1 := a1 >> count
5372*35ffd701SAndroid Build Coastguard Worker // r2 := a2 >> count
5373*35ffd701SAndroid Build Coastguard Worker // r3 := a3 >> count
5374*35ffd701SAndroid Build Coastguard Worker //
5375*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/ce40009e(v%3dvs.100).aspx
_mm_sra_epi32(__m128i a,__m128i count)5376*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sra_epi32(__m128i a, __m128i count)
5377*35ffd701SAndroid Build Coastguard Worker {
5378*35ffd701SAndroid Build Coastguard Worker int64_t c = (int64_t) vget_low_s64((int64x2_t) count);
5379*35ffd701SAndroid Build Coastguard Worker if (unlikely(c > 31))
5380*35ffd701SAndroid Build Coastguard Worker return _mm_cmplt_epi32(a, _mm_setzero_si128());
5381*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vshlq_s32((int32x4_t) a, vdupq_n_s32(-c)));
5382*35ffd701SAndroid Build Coastguard Worker }
5383*35ffd701SAndroid Build Coastguard Worker
5384*35ffd701SAndroid Build Coastguard Worker // Shift packed 16-bit integers in a right by imm while shifting in sign
5385*35ffd701SAndroid Build Coastguard Worker // bits, and store the results in dst.
5386*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi16
_mm_srai_epi16(__m128i a,int imm)5387*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_srai_epi16(__m128i a, int imm)
5388*35ffd701SAndroid Build Coastguard Worker {
5389*35ffd701SAndroid Build Coastguard Worker const int count = (imm & ~15) ? 15 : imm;
5390*35ffd701SAndroid Build Coastguard Worker return (__m128i) vshlq_s16((int16x8_t) a, vdupq_n_s16(-count));
5391*35ffd701SAndroid Build Coastguard Worker }
5392*35ffd701SAndroid Build Coastguard Worker
5393*35ffd701SAndroid Build Coastguard Worker // Shift packed 32-bit integers in a right by imm8 while shifting in sign bits,
5394*35ffd701SAndroid Build Coastguard Worker // and store the results in dst.
5395*35ffd701SAndroid Build Coastguard Worker //
5396*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
5397*35ffd701SAndroid Build Coastguard Worker // i := j*32
5398*35ffd701SAndroid Build Coastguard Worker // IF imm8[7:0] > 31
5399*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0)
5400*35ffd701SAndroid Build Coastguard Worker // ELSE
5401*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := SignExtend32(a[i+31:i] >> imm8[7:0])
5402*35ffd701SAndroid Build Coastguard Worker // FI
5403*35ffd701SAndroid Build Coastguard Worker // ENDFOR
5404*35ffd701SAndroid Build Coastguard Worker //
5405*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi32
5406*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, __constrange(0,255) int imm)
5407*35ffd701SAndroid Build Coastguard Worker #define _mm_srai_epi32(a, imm) \
5408*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5409*35ffd701SAndroid Build Coastguard Worker __m128i ret; \
5410*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) == 0)) { \
5411*35ffd701SAndroid Build Coastguard Worker ret = a; \
5412*35ffd701SAndroid Build Coastguard Worker } else if (likely(0 < (imm) && (imm) < 32)) { \
5413*35ffd701SAndroid Build Coastguard Worker ret = vreinterpretq_m128i_s32( \
5414*35ffd701SAndroid Build Coastguard Worker vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(-imm))); \
5415*35ffd701SAndroid Build Coastguard Worker } else { \
5416*35ffd701SAndroid Build Coastguard Worker ret = vreinterpretq_m128i_s32( \
5417*35ffd701SAndroid Build Coastguard Worker vshrq_n_s32(vreinterpretq_s32_m128i(a), 31)); \
5418*35ffd701SAndroid Build Coastguard Worker } \
5419*35ffd701SAndroid Build Coastguard Worker ret; \
5420*35ffd701SAndroid Build Coastguard Worker })
5421*35ffd701SAndroid Build Coastguard Worker
5422*35ffd701SAndroid Build Coastguard Worker // Shifts the 8 signed or unsigned 16-bit integers in a right by count bits
5423*35ffd701SAndroid Build Coastguard Worker // while shifting in zeros.
5424*35ffd701SAndroid Build Coastguard Worker //
5425*35ffd701SAndroid Build Coastguard Worker // r0 := srl(a0, count)
5426*35ffd701SAndroid Build Coastguard Worker // r1 := srl(a1, count)
5427*35ffd701SAndroid Build Coastguard Worker // ...
5428*35ffd701SAndroid Build Coastguard Worker // r7 := srl(a7, count)
5429*35ffd701SAndroid Build Coastguard Worker //
5430*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/wd5ax830(v%3dvs.90).aspx
_mm_srl_epi16(__m128i a,__m128i count)5431*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_srl_epi16(__m128i a, __m128i count)
5432*35ffd701SAndroid Build Coastguard Worker {
5433*35ffd701SAndroid Build Coastguard Worker uint64_t c = vreinterpretq_nth_u64_m128i(count, 0);
5434*35ffd701SAndroid Build Coastguard Worker if (unlikely(c > 15))
5435*35ffd701SAndroid Build Coastguard Worker return _mm_setzero_si128();
5436*35ffd701SAndroid Build Coastguard Worker
5437*35ffd701SAndroid Build Coastguard Worker int16x8_t vc = vdupq_n_s16(-(int16_t) c);
5438*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(vshlq_u16(vreinterpretq_u16_m128i(a), vc));
5439*35ffd701SAndroid Build Coastguard Worker }
5440*35ffd701SAndroid Build Coastguard Worker
5441*35ffd701SAndroid Build Coastguard Worker // Shifts the 4 signed or unsigned 32-bit integers in a right by count bits
5442*35ffd701SAndroid Build Coastguard Worker // while shifting in zeros.
5443*35ffd701SAndroid Build Coastguard Worker //
5444*35ffd701SAndroid Build Coastguard Worker // r0 := srl(a0, count)
5445*35ffd701SAndroid Build Coastguard Worker // r1 := srl(a1, count)
5446*35ffd701SAndroid Build Coastguard Worker // r2 := srl(a2, count)
5447*35ffd701SAndroid Build Coastguard Worker // r3 := srl(a3, count)
5448*35ffd701SAndroid Build Coastguard Worker //
5449*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/a9cbttf4(v%3dvs.90).aspx
_mm_srl_epi32(__m128i a,__m128i count)5450*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_srl_epi32(__m128i a, __m128i count)
5451*35ffd701SAndroid Build Coastguard Worker {
5452*35ffd701SAndroid Build Coastguard Worker uint64_t c = vreinterpretq_nth_u64_m128i(count, 0);
5453*35ffd701SAndroid Build Coastguard Worker if (unlikely(c > 31))
5454*35ffd701SAndroid Build Coastguard Worker return _mm_setzero_si128();
5455*35ffd701SAndroid Build Coastguard Worker
5456*35ffd701SAndroid Build Coastguard Worker int32x4_t vc = vdupq_n_s32(-(int32_t) c);
5457*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u32(vshlq_u32(vreinterpretq_u32_m128i(a), vc));
5458*35ffd701SAndroid Build Coastguard Worker }
5459*35ffd701SAndroid Build Coastguard Worker
5460*35ffd701SAndroid Build Coastguard Worker // Shifts the 2 signed or unsigned 64-bit integers in a right by count bits
5461*35ffd701SAndroid Build Coastguard Worker // while shifting in zeros.
5462*35ffd701SAndroid Build Coastguard Worker //
5463*35ffd701SAndroid Build Coastguard Worker // r0 := srl(a0, count)
5464*35ffd701SAndroid Build Coastguard Worker // r1 := srl(a1, count)
5465*35ffd701SAndroid Build Coastguard Worker //
5466*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/yf6cf9k8(v%3dvs.90).aspx
_mm_srl_epi64(__m128i a,__m128i count)5467*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_srl_epi64(__m128i a, __m128i count)
5468*35ffd701SAndroid Build Coastguard Worker {
5469*35ffd701SAndroid Build Coastguard Worker uint64_t c = vreinterpretq_nth_u64_m128i(count, 0);
5470*35ffd701SAndroid Build Coastguard Worker if (unlikely(c > 63))
5471*35ffd701SAndroid Build Coastguard Worker return _mm_setzero_si128();
5472*35ffd701SAndroid Build Coastguard Worker
5473*35ffd701SAndroid Build Coastguard Worker int64x2_t vc = vdupq_n_s64(-(int64_t) c);
5474*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(vshlq_u64(vreinterpretq_u64_m128i(a), vc));
5475*35ffd701SAndroid Build Coastguard Worker }
5476*35ffd701SAndroid Build Coastguard Worker
5477*35ffd701SAndroid Build Coastguard Worker // Shift packed 16-bit integers in a right by imm8 while shifting in zeros, and
5478*35ffd701SAndroid Build Coastguard Worker // store the results in dst.
5479*35ffd701SAndroid Build Coastguard Worker //
5480*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
5481*35ffd701SAndroid Build Coastguard Worker // i := j*16
5482*35ffd701SAndroid Build Coastguard Worker // IF imm8[7:0] > 15
5483*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := 0
5484*35ffd701SAndroid Build Coastguard Worker // ELSE
5485*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := ZeroExtend16(a[i+15:i] >> imm8[7:0])
5486*35ffd701SAndroid Build Coastguard Worker // FI
5487*35ffd701SAndroid Build Coastguard Worker // ENDFOR
5488*35ffd701SAndroid Build Coastguard Worker //
5489*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi16
5490*35ffd701SAndroid Build Coastguard Worker #define _mm_srli_epi16(a, imm) \
5491*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5492*35ffd701SAndroid Build Coastguard Worker __m128i ret; \
5493*35ffd701SAndroid Build Coastguard Worker if (unlikely(imm) == 0) { \
5494*35ffd701SAndroid Build Coastguard Worker ret = a; \
5495*35ffd701SAndroid Build Coastguard Worker } else if (likely(0 < (imm) && (imm) < 16)) { \
5496*35ffd701SAndroid Build Coastguard Worker ret = vreinterpretq_m128i_u16( \
5497*35ffd701SAndroid Build Coastguard Worker vshlq_u16(vreinterpretq_u16_m128i(a), vdupq_n_s16(-imm))); \
5498*35ffd701SAndroid Build Coastguard Worker } else { \
5499*35ffd701SAndroid Build Coastguard Worker ret = _mm_setzero_si128(); \
5500*35ffd701SAndroid Build Coastguard Worker } \
5501*35ffd701SAndroid Build Coastguard Worker ret; \
5502*35ffd701SAndroid Build Coastguard Worker })
5503*35ffd701SAndroid Build Coastguard Worker
5504*35ffd701SAndroid Build Coastguard Worker // Shift packed 32-bit integers in a right by imm8 while shifting in zeros, and
5505*35ffd701SAndroid Build Coastguard Worker // store the results in dst.
5506*35ffd701SAndroid Build Coastguard Worker //
5507*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
5508*35ffd701SAndroid Build Coastguard Worker // i := j*32
5509*35ffd701SAndroid Build Coastguard Worker // IF imm8[7:0] > 31
5510*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := 0
5511*35ffd701SAndroid Build Coastguard Worker // ELSE
5512*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := ZeroExtend32(a[i+31:i] >> imm8[7:0])
5513*35ffd701SAndroid Build Coastguard Worker // FI
5514*35ffd701SAndroid Build Coastguard Worker // ENDFOR
5515*35ffd701SAndroid Build Coastguard Worker //
5516*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi32
5517*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_srli_epi32(__m128i a, __constrange(0,255) int imm)
5518*35ffd701SAndroid Build Coastguard Worker #define _mm_srli_epi32(a, imm) \
5519*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5520*35ffd701SAndroid Build Coastguard Worker __m128i ret; \
5521*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) == 0)) { \
5522*35ffd701SAndroid Build Coastguard Worker ret = a; \
5523*35ffd701SAndroid Build Coastguard Worker } else if (likely(0 < (imm) && (imm) < 32)) { \
5524*35ffd701SAndroid Build Coastguard Worker ret = vreinterpretq_m128i_u32( \
5525*35ffd701SAndroid Build Coastguard Worker vshlq_u32(vreinterpretq_u32_m128i(a), vdupq_n_s32(-imm))); \
5526*35ffd701SAndroid Build Coastguard Worker } else { \
5527*35ffd701SAndroid Build Coastguard Worker ret = _mm_setzero_si128(); \
5528*35ffd701SAndroid Build Coastguard Worker } \
5529*35ffd701SAndroid Build Coastguard Worker ret; \
5530*35ffd701SAndroid Build Coastguard Worker })
5531*35ffd701SAndroid Build Coastguard Worker
5532*35ffd701SAndroid Build Coastguard Worker // Shift packed 64-bit integers in a right by imm8 while shifting in zeros, and
5533*35ffd701SAndroid Build Coastguard Worker // store the results in dst.
5534*35ffd701SAndroid Build Coastguard Worker //
5535*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
5536*35ffd701SAndroid Build Coastguard Worker // i := j*64
5537*35ffd701SAndroid Build Coastguard Worker // IF imm8[7:0] > 63
5538*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := 0
5539*35ffd701SAndroid Build Coastguard Worker // ELSE
5540*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := ZeroExtend64(a[i+63:i] >> imm8[7:0])
5541*35ffd701SAndroid Build Coastguard Worker // FI
5542*35ffd701SAndroid Build Coastguard Worker // ENDFOR
5543*35ffd701SAndroid Build Coastguard Worker //
5544*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi64
5545*35ffd701SAndroid Build Coastguard Worker #define _mm_srli_epi64(a, imm) \
5546*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5547*35ffd701SAndroid Build Coastguard Worker __m128i ret; \
5548*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) == 0)) { \
5549*35ffd701SAndroid Build Coastguard Worker ret = a; \
5550*35ffd701SAndroid Build Coastguard Worker } else if (likely(0 < (imm) && (imm) < 64)) { \
5551*35ffd701SAndroid Build Coastguard Worker ret = vreinterpretq_m128i_u64( \
5552*35ffd701SAndroid Build Coastguard Worker vshlq_u64(vreinterpretq_u64_m128i(a), vdupq_n_s64(-imm))); \
5553*35ffd701SAndroid Build Coastguard Worker } else { \
5554*35ffd701SAndroid Build Coastguard Worker ret = _mm_setzero_si128(); \
5555*35ffd701SAndroid Build Coastguard Worker } \
5556*35ffd701SAndroid Build Coastguard Worker ret; \
5557*35ffd701SAndroid Build Coastguard Worker })
5558*35ffd701SAndroid Build Coastguard Worker
5559*35ffd701SAndroid Build Coastguard Worker // Shifts the 128 - bit value in a right by imm bytes while shifting in
5560*35ffd701SAndroid Build Coastguard Worker // zeros.imm must be an immediate.
5561*35ffd701SAndroid Build Coastguard Worker //
5562*35ffd701SAndroid Build Coastguard Worker // r := srl(a, imm*8)
5563*35ffd701SAndroid Build Coastguard Worker //
5564*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/305w28yz(v=vs.100).aspx
5565*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE _mm_srli_si128(__m128i a, __constrange(0,255) int imm)
5566*35ffd701SAndroid Build Coastguard Worker #define _mm_srli_si128(a, imm) \
5567*35ffd701SAndroid Build Coastguard Worker __extension__({ \
5568*35ffd701SAndroid Build Coastguard Worker __m128i ret; \
5569*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) <= 0)) { \
5570*35ffd701SAndroid Build Coastguard Worker ret = a; \
5571*35ffd701SAndroid Build Coastguard Worker } \
5572*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) > 15)) { \
5573*35ffd701SAndroid Build Coastguard Worker ret = _mm_setzero_si128(); \
5574*35ffd701SAndroid Build Coastguard Worker } else { \
5575*35ffd701SAndroid Build Coastguard Worker ret = vreinterpretq_m128i_s8( \
5576*35ffd701SAndroid Build Coastguard Worker vextq_s8(vreinterpretq_s8_m128i(a), vdupq_n_s8(0), (imm))); \
5577*35ffd701SAndroid Build Coastguard Worker } \
5578*35ffd701SAndroid Build Coastguard Worker ret; \
5579*35ffd701SAndroid Build Coastguard Worker })
5580*35ffd701SAndroid Build Coastguard Worker
5581*35ffd701SAndroid Build Coastguard Worker // Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point
5582*35ffd701SAndroid Build Coastguard Worker // elements) from a into memory. mem_addr must be aligned on a 16-byte boundary
5583*35ffd701SAndroid Build Coastguard Worker // or a general-protection exception may be generated.
5584*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd
_mm_store_pd(double * mem_addr,__m128d a)5585*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_store_pd(double *mem_addr, __m128d a)
5586*35ffd701SAndroid Build Coastguard Worker {
5587*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5588*35ffd701SAndroid Build Coastguard Worker vst1q_f64((float64_t *) mem_addr, vreinterpretq_f64_m128d(a));
5589*35ffd701SAndroid Build Coastguard Worker #else
5590*35ffd701SAndroid Build Coastguard Worker vst1q_f32((float32_t *) mem_addr, vreinterpretq_f32_m128d(a));
5591*35ffd701SAndroid Build Coastguard Worker #endif
5592*35ffd701SAndroid Build Coastguard Worker }
5593*35ffd701SAndroid Build Coastguard Worker
5594*35ffd701SAndroid Build Coastguard Worker // Store the lower double-precision (64-bit) floating-point element from a into
5595*35ffd701SAndroid Build Coastguard Worker // 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte
5596*35ffd701SAndroid Build Coastguard Worker // boundary or a general-protection exception may be generated.
5597*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd1
_mm_store_pd1(double * mem_addr,__m128d a)5598*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_store_pd1(double *mem_addr, __m128d a)
5599*35ffd701SAndroid Build Coastguard Worker {
5600*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5601*35ffd701SAndroid Build Coastguard Worker float64x1_t a_low = vget_low_f64(vreinterpretq_f64_m128d(a));
5602*35ffd701SAndroid Build Coastguard Worker vst1q_f64((float64_t *) mem_addr,
5603*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f64_m128d(vcombine_f64(a_low, a_low)));
5604*35ffd701SAndroid Build Coastguard Worker #else
5605*35ffd701SAndroid Build Coastguard Worker float32x2_t a_low = vget_low_f32(vreinterpretq_f32_m128d(a));
5606*35ffd701SAndroid Build Coastguard Worker vst1q_f32((float32_t *) mem_addr,
5607*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128d(vcombine_f32(a_low, a_low)));
5608*35ffd701SAndroid Build Coastguard Worker #endif
5609*35ffd701SAndroid Build Coastguard Worker }
5610*35ffd701SAndroid Build Coastguard Worker
5611*35ffd701SAndroid Build Coastguard Worker // Store the lower double-precision (64-bit) floating-point element from a into
5612*35ffd701SAndroid Build Coastguard Worker // memory. mem_addr does not need to be aligned on any particular boundary.
5613*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_store_sd
_mm_store_sd(double * mem_addr,__m128d a)5614*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_store_sd(double *mem_addr, __m128d a)
5615*35ffd701SAndroid Build Coastguard Worker {
5616*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5617*35ffd701SAndroid Build Coastguard Worker vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a)));
5618*35ffd701SAndroid Build Coastguard Worker #else
5619*35ffd701SAndroid Build Coastguard Worker vst1_u64((uint64_t *) mem_addr, vget_low_u64(vreinterpretq_u64_m128d(a)));
5620*35ffd701SAndroid Build Coastguard Worker #endif
5621*35ffd701SAndroid Build Coastguard Worker }
5622*35ffd701SAndroid Build Coastguard Worker
5623*35ffd701SAndroid Build Coastguard Worker // Stores four 32-bit integer values as (as a __m128i value) at the address p.
5624*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx
_mm_store_si128(__m128i * p,__m128i a)5625*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a)
5626*35ffd701SAndroid Build Coastguard Worker {
5627*35ffd701SAndroid Build Coastguard Worker vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a));
5628*35ffd701SAndroid Build Coastguard Worker }
5629*35ffd701SAndroid Build Coastguard Worker
5630*35ffd701SAndroid Build Coastguard Worker // Store the lower double-precision (64-bit) floating-point element from a into
5631*35ffd701SAndroid Build Coastguard Worker // 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte
5632*35ffd701SAndroid Build Coastguard Worker // boundary or a general-protection exception may be generated.
5633*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=9,526,5601&text=_mm_store1_pd
5634*35ffd701SAndroid Build Coastguard Worker #define _mm_store1_pd _mm_store_pd1
5635*35ffd701SAndroid Build Coastguard Worker
5636*35ffd701SAndroid Build Coastguard Worker // Store the upper double-precision (64-bit) floating-point element from a into
5637*35ffd701SAndroid Build Coastguard Worker // memory.
5638*35ffd701SAndroid Build Coastguard Worker //
5639*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+63:mem_addr] := a[127:64]
5640*35ffd701SAndroid Build Coastguard Worker //
5641*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeh_pd
_mm_storeh_pd(double * mem_addr,__m128d a)5642*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storeh_pd(double *mem_addr, __m128d a)
5643*35ffd701SAndroid Build Coastguard Worker {
5644*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5645*35ffd701SAndroid Build Coastguard Worker vst1_f64((float64_t *) mem_addr, vget_high_f64(vreinterpretq_f64_m128d(a)));
5646*35ffd701SAndroid Build Coastguard Worker #else
5647*35ffd701SAndroid Build Coastguard Worker vst1_f32((float32_t *) mem_addr, vget_high_f32(vreinterpretq_f32_m128d(a)));
5648*35ffd701SAndroid Build Coastguard Worker #endif
5649*35ffd701SAndroid Build Coastguard Worker }
5650*35ffd701SAndroid Build Coastguard Worker
5651*35ffd701SAndroid Build Coastguard Worker // Reads the lower 64 bits of b and stores them into the lower 64 bits of a.
5652*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/hhwf428f%28v=vs.90%29.aspx
_mm_storel_epi64(__m128i * a,__m128i b)5653*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storel_epi64(__m128i *a, __m128i b)
5654*35ffd701SAndroid Build Coastguard Worker {
5655*35ffd701SAndroid Build Coastguard Worker uint64x1_t hi = vget_high_u64(vreinterpretq_u64_m128i(*a));
5656*35ffd701SAndroid Build Coastguard Worker uint64x1_t lo = vget_low_u64(vreinterpretq_u64_m128i(b));
5657*35ffd701SAndroid Build Coastguard Worker *a = vreinterpretq_m128i_u64(vcombine_u64(lo, hi));
5658*35ffd701SAndroid Build Coastguard Worker }
5659*35ffd701SAndroid Build Coastguard Worker
5660*35ffd701SAndroid Build Coastguard Worker // Store the lower double-precision (64-bit) floating-point element from a into
5661*35ffd701SAndroid Build Coastguard Worker // memory.
5662*35ffd701SAndroid Build Coastguard Worker //
5663*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+63:mem_addr] := a[63:0]
5664*35ffd701SAndroid Build Coastguard Worker //
5665*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storel_pd
_mm_storel_pd(double * mem_addr,__m128d a)5666*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storel_pd(double *mem_addr, __m128d a)
5667*35ffd701SAndroid Build Coastguard Worker {
5668*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5669*35ffd701SAndroid Build Coastguard Worker vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a)));
5670*35ffd701SAndroid Build Coastguard Worker #else
5671*35ffd701SAndroid Build Coastguard Worker vst1_f32((float32_t *) mem_addr, vget_low_f32(vreinterpretq_f32_m128d(a)));
5672*35ffd701SAndroid Build Coastguard Worker #endif
5673*35ffd701SAndroid Build Coastguard Worker }
5674*35ffd701SAndroid Build Coastguard Worker
5675*35ffd701SAndroid Build Coastguard Worker // Store 2 double-precision (64-bit) floating-point elements from a into memory
5676*35ffd701SAndroid Build Coastguard Worker // in reverse order. mem_addr must be aligned on a 16-byte boundary or a
5677*35ffd701SAndroid Build Coastguard Worker // general-protection exception may be generated.
5678*35ffd701SAndroid Build Coastguard Worker //
5679*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+63:mem_addr] := a[127:64]
5680*35ffd701SAndroid Build Coastguard Worker // MEM[mem_addr+127:mem_addr+64] := a[63:0]
5681*35ffd701SAndroid Build Coastguard Worker //
5682*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_pd
_mm_storer_pd(double * mem_addr,__m128d a)5683*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storer_pd(double *mem_addr, __m128d a)
5684*35ffd701SAndroid Build Coastguard Worker {
5685*35ffd701SAndroid Build Coastguard Worker float32x4_t f = vreinterpretq_f32_m128d(a);
5686*35ffd701SAndroid Build Coastguard Worker _mm_store_pd(mem_addr, vreinterpretq_m128d_f32(vextq_f32(f, f, 2)));
5687*35ffd701SAndroid Build Coastguard Worker }
5688*35ffd701SAndroid Build Coastguard Worker
5689*35ffd701SAndroid Build Coastguard Worker // Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point
5690*35ffd701SAndroid Build Coastguard Worker // elements) from a into memory. mem_addr does not need to be aligned on any
5691*35ffd701SAndroid Build Coastguard Worker // particular boundary.
5692*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_pd
_mm_storeu_pd(double * mem_addr,__m128d a)5693*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storeu_pd(double *mem_addr, __m128d a)
5694*35ffd701SAndroid Build Coastguard Worker {
5695*35ffd701SAndroid Build Coastguard Worker _mm_store_pd(mem_addr, a);
5696*35ffd701SAndroid Build Coastguard Worker }
5697*35ffd701SAndroid Build Coastguard Worker
5698*35ffd701SAndroid Build Coastguard Worker // Stores 128-bits of integer data a at the address p.
5699*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si128
_mm_storeu_si128(__m128i * p,__m128i a)5700*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a)
5701*35ffd701SAndroid Build Coastguard Worker {
5702*35ffd701SAndroid Build Coastguard Worker vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a));
5703*35ffd701SAndroid Build Coastguard Worker }
5704*35ffd701SAndroid Build Coastguard Worker
5705*35ffd701SAndroid Build Coastguard Worker // Stores 32-bits of integer data a at the address p.
5706*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si32
_mm_storeu_si32(void * p,__m128i a)5707*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_storeu_si32(void *p, __m128i a)
5708*35ffd701SAndroid Build Coastguard Worker {
5709*35ffd701SAndroid Build Coastguard Worker vst1q_lane_s32((int32_t *) p, vreinterpretq_s32_m128i(a), 0);
5710*35ffd701SAndroid Build Coastguard Worker }
5711*35ffd701SAndroid Build Coastguard Worker
5712*35ffd701SAndroid Build Coastguard Worker // Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point
5713*35ffd701SAndroid Build Coastguard Worker // elements) from a into memory using a non-temporal memory hint. mem_addr must
5714*35ffd701SAndroid Build Coastguard Worker // be aligned on a 16-byte boundary or a general-protection exception may be
5715*35ffd701SAndroid Build Coastguard Worker // generated.
5716*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pd
_mm_stream_pd(double * p,__m128d a)5717*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_stream_pd(double *p, __m128d a)
5718*35ffd701SAndroid Build Coastguard Worker {
5719*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_nontemporal_store)
5720*35ffd701SAndroid Build Coastguard Worker __builtin_nontemporal_store(a, (float32x4_t *) p);
5721*35ffd701SAndroid Build Coastguard Worker #elif defined(__aarch64__)
5722*35ffd701SAndroid Build Coastguard Worker vst1q_f64(p, vreinterpretq_f64_m128d(a));
5723*35ffd701SAndroid Build Coastguard Worker #else
5724*35ffd701SAndroid Build Coastguard Worker vst1q_s64((int64_t *) p, vreinterpretq_s64_m128d(a));
5725*35ffd701SAndroid Build Coastguard Worker #endif
5726*35ffd701SAndroid Build Coastguard Worker }
5727*35ffd701SAndroid Build Coastguard Worker
5728*35ffd701SAndroid Build Coastguard Worker // Stores the data in a to the address p without polluting the caches. If the
5729*35ffd701SAndroid Build Coastguard Worker // cache line containing address p is already in the cache, the cache will be
5730*35ffd701SAndroid Build Coastguard Worker // updated.
5731*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/ba08y07y%28v=vs.90%29.aspx
_mm_stream_si128(__m128i * p,__m128i a)5732*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a)
5733*35ffd701SAndroid Build Coastguard Worker {
5734*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_nontemporal_store)
5735*35ffd701SAndroid Build Coastguard Worker __builtin_nontemporal_store(a, p);
5736*35ffd701SAndroid Build Coastguard Worker #else
5737*35ffd701SAndroid Build Coastguard Worker vst1q_s64((int64_t *) p, vreinterpretq_s64_m128i(a));
5738*35ffd701SAndroid Build Coastguard Worker #endif
5739*35ffd701SAndroid Build Coastguard Worker }
5740*35ffd701SAndroid Build Coastguard Worker
5741*35ffd701SAndroid Build Coastguard Worker // Store 32-bit integer a into memory using a non-temporal hint to minimize
5742*35ffd701SAndroid Build Coastguard Worker // cache pollution. If the cache line containing address mem_addr is already in
5743*35ffd701SAndroid Build Coastguard Worker // the cache, the cache will be updated.
5744*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_si32
_mm_stream_si32(int * p,int a)5745*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE void _mm_stream_si32(int *p, int a)
5746*35ffd701SAndroid Build Coastguard Worker {
5747*35ffd701SAndroid Build Coastguard Worker vst1q_lane_s32((int32_t *) p, vdupq_n_s32(a), 0);
5748*35ffd701SAndroid Build Coastguard Worker }
5749*35ffd701SAndroid Build Coastguard Worker
5750*35ffd701SAndroid Build Coastguard Worker // Subtract packed 16-bit integers in b from packed 16-bit integers in a, and
5751*35ffd701SAndroid Build Coastguard Worker // store the results in dst.
5752*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi16
_mm_sub_epi16(__m128i a,__m128i b)5753*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sub_epi16(__m128i a, __m128i b)
5754*35ffd701SAndroid Build Coastguard Worker {
5755*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
5756*35ffd701SAndroid Build Coastguard Worker vsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
5757*35ffd701SAndroid Build Coastguard Worker }
5758*35ffd701SAndroid Build Coastguard Worker
5759*35ffd701SAndroid Build Coastguard Worker // Subtracts the 4 signed or unsigned 32-bit integers of b from the 4 signed or
5760*35ffd701SAndroid Build Coastguard Worker // unsigned 32-bit integers of a.
5761*35ffd701SAndroid Build Coastguard Worker //
5762*35ffd701SAndroid Build Coastguard Worker // r0 := a0 - b0
5763*35ffd701SAndroid Build Coastguard Worker // r1 := a1 - b1
5764*35ffd701SAndroid Build Coastguard Worker // r2 := a2 - b2
5765*35ffd701SAndroid Build Coastguard Worker // r3 := a3 - b3
5766*35ffd701SAndroid Build Coastguard Worker //
5767*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/fhh866h0(v=vs.100).aspx
_mm_sub_epi32(__m128i a,__m128i b)5768*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sub_epi32(__m128i a, __m128i b)
5769*35ffd701SAndroid Build Coastguard Worker {
5770*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
5771*35ffd701SAndroid Build Coastguard Worker vsubq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
5772*35ffd701SAndroid Build Coastguard Worker }
5773*35ffd701SAndroid Build Coastguard Worker
5774*35ffd701SAndroid Build Coastguard Worker // Subtract 2 packed 64-bit integers in b from 2 packed 64-bit integers in a,
5775*35ffd701SAndroid Build Coastguard Worker // and store the results in dst.
5776*35ffd701SAndroid Build Coastguard Worker // r0 := a0 - b0
5777*35ffd701SAndroid Build Coastguard Worker // r1 := a1 - b1
_mm_sub_epi64(__m128i a,__m128i b)5778*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sub_epi64(__m128i a, __m128i b)
5779*35ffd701SAndroid Build Coastguard Worker {
5780*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(
5781*35ffd701SAndroid Build Coastguard Worker vsubq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b)));
5782*35ffd701SAndroid Build Coastguard Worker }
5783*35ffd701SAndroid Build Coastguard Worker
5784*35ffd701SAndroid Build Coastguard Worker // Subtract packed 8-bit integers in b from packed 8-bit integers in a, and
5785*35ffd701SAndroid Build Coastguard Worker // store the results in dst.
5786*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi8
_mm_sub_epi8(__m128i a,__m128i b)5787*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sub_epi8(__m128i a, __m128i b)
5788*35ffd701SAndroid Build Coastguard Worker {
5789*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
5790*35ffd701SAndroid Build Coastguard Worker vsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
5791*35ffd701SAndroid Build Coastguard Worker }
5792*35ffd701SAndroid Build Coastguard Worker
5793*35ffd701SAndroid Build Coastguard Worker // Subtract packed double-precision (64-bit) floating-point elements in b from
5794*35ffd701SAndroid Build Coastguard Worker // packed double-precision (64-bit) floating-point elements in a, and store the
5795*35ffd701SAndroid Build Coastguard Worker // results in dst.
5796*35ffd701SAndroid Build Coastguard Worker //
5797*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
5798*35ffd701SAndroid Build Coastguard Worker // i := j*64
5799*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := a[i+63:i] - b[i+63:i]
5800*35ffd701SAndroid Build Coastguard Worker // ENDFOR
5801*35ffd701SAndroid Build Coastguard Worker //
5802*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_sub_pd
_mm_sub_pd(__m128d a,__m128d b)5803*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_sub_pd(__m128d a, __m128d b)
5804*35ffd701SAndroid Build Coastguard Worker {
5805*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5806*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
5807*35ffd701SAndroid Build Coastguard Worker vsubq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
5808*35ffd701SAndroid Build Coastguard Worker #else
5809*35ffd701SAndroid Build Coastguard Worker double *da = (double *) &a;
5810*35ffd701SAndroid Build Coastguard Worker double *db = (double *) &b;
5811*35ffd701SAndroid Build Coastguard Worker double c[2];
5812*35ffd701SAndroid Build Coastguard Worker c[0] = da[0] - db[0];
5813*35ffd701SAndroid Build Coastguard Worker c[1] = da[1] - db[1];
5814*35ffd701SAndroid Build Coastguard Worker return vld1q_f32((float32_t *) c);
5815*35ffd701SAndroid Build Coastguard Worker #endif
5816*35ffd701SAndroid Build Coastguard Worker }
5817*35ffd701SAndroid Build Coastguard Worker
5818*35ffd701SAndroid Build Coastguard Worker // Subtract the lower double-precision (64-bit) floating-point element in b from
5819*35ffd701SAndroid Build Coastguard Worker // the lower double-precision (64-bit) floating-point element in a, store the
5820*35ffd701SAndroid Build Coastguard Worker // result in the lower element of dst, and copy the upper element from a to the
5821*35ffd701SAndroid Build Coastguard Worker // upper element of dst.
5822*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_sd
_mm_sub_sd(__m128d a,__m128d b)5823*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_sub_sd(__m128d a, __m128d b)
5824*35ffd701SAndroid Build Coastguard Worker {
5825*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_sub_pd(a, b));
5826*35ffd701SAndroid Build Coastguard Worker }
5827*35ffd701SAndroid Build Coastguard Worker
5828*35ffd701SAndroid Build Coastguard Worker // Subtract 64-bit integer b from 64-bit integer a, and store the result in dst.
5829*35ffd701SAndroid Build Coastguard Worker //
5830*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := a[63:0] - b[63:0]
5831*35ffd701SAndroid Build Coastguard Worker //
5832*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_si64
_mm_sub_si64(__m64 a,__m64 b)5833*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_sub_si64(__m64 a, __m64 b)
5834*35ffd701SAndroid Build Coastguard Worker {
5835*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s64(
5836*35ffd701SAndroid Build Coastguard Worker vsub_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b)));
5837*35ffd701SAndroid Build Coastguard Worker }
5838*35ffd701SAndroid Build Coastguard Worker
5839*35ffd701SAndroid Build Coastguard Worker // Subtracts the 8 signed 16-bit integers of b from the 8 signed 16-bit integers
5840*35ffd701SAndroid Build Coastguard Worker // of a and saturates.
5841*35ffd701SAndroid Build Coastguard Worker //
5842*35ffd701SAndroid Build Coastguard Worker // r0 := SignedSaturate(a0 - b0)
5843*35ffd701SAndroid Build Coastguard Worker // r1 := SignedSaturate(a1 - b1)
5844*35ffd701SAndroid Build Coastguard Worker // ...
5845*35ffd701SAndroid Build Coastguard Worker // r7 := SignedSaturate(a7 - b7)
5846*35ffd701SAndroid Build Coastguard Worker //
5847*35ffd701SAndroid Build Coastguard Worker // https://technet.microsoft.com/en-us/subscriptions/3247z5b8(v=vs.90)
_mm_subs_epi16(__m128i a,__m128i b)5848*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_subs_epi16(__m128i a, __m128i b)
5849*35ffd701SAndroid Build Coastguard Worker {
5850*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
5851*35ffd701SAndroid Build Coastguard Worker vqsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
5852*35ffd701SAndroid Build Coastguard Worker }
5853*35ffd701SAndroid Build Coastguard Worker
5854*35ffd701SAndroid Build Coastguard Worker // Subtracts the 16 signed 8-bit integers of b from the 16 signed 8-bit integers
5855*35ffd701SAndroid Build Coastguard Worker // of a and saturates.
5856*35ffd701SAndroid Build Coastguard Worker //
5857*35ffd701SAndroid Build Coastguard Worker // r0 := SignedSaturate(a0 - b0)
5858*35ffd701SAndroid Build Coastguard Worker // r1 := SignedSaturate(a1 - b1)
5859*35ffd701SAndroid Build Coastguard Worker // ...
5860*35ffd701SAndroid Build Coastguard Worker // r15 := SignedSaturate(a15 - b15)
5861*35ffd701SAndroid Build Coastguard Worker //
5862*35ffd701SAndroid Build Coastguard Worker // https://technet.microsoft.com/en-us/subscriptions/by7kzks1(v=vs.90)
_mm_subs_epi8(__m128i a,__m128i b)5863*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_subs_epi8(__m128i a, __m128i b)
5864*35ffd701SAndroid Build Coastguard Worker {
5865*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
5866*35ffd701SAndroid Build Coastguard Worker vqsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
5867*35ffd701SAndroid Build Coastguard Worker }
5868*35ffd701SAndroid Build Coastguard Worker
5869*35ffd701SAndroid Build Coastguard Worker // Subtracts the 8 unsigned 16-bit integers of bfrom the 8 unsigned 16-bit
5870*35ffd701SAndroid Build Coastguard Worker // integers of a and saturates..
5871*35ffd701SAndroid Build Coastguard Worker // https://technet.microsoft.com/en-us/subscriptions/index/f44y0s19(v=vs.90).aspx
_mm_subs_epu16(__m128i a,__m128i b)5872*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_subs_epu16(__m128i a, __m128i b)
5873*35ffd701SAndroid Build Coastguard Worker {
5874*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(
5875*35ffd701SAndroid Build Coastguard Worker vqsubq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b)));
5876*35ffd701SAndroid Build Coastguard Worker }
5877*35ffd701SAndroid Build Coastguard Worker
5878*35ffd701SAndroid Build Coastguard Worker // Subtracts the 16 unsigned 8-bit integers of b from the 16 unsigned 8-bit
5879*35ffd701SAndroid Build Coastguard Worker // integers of a and saturates.
5880*35ffd701SAndroid Build Coastguard Worker //
5881*35ffd701SAndroid Build Coastguard Worker // r0 := UnsignedSaturate(a0 - b0)
5882*35ffd701SAndroid Build Coastguard Worker // r1 := UnsignedSaturate(a1 - b1)
5883*35ffd701SAndroid Build Coastguard Worker // ...
5884*35ffd701SAndroid Build Coastguard Worker // r15 := UnsignedSaturate(a15 - b15)
5885*35ffd701SAndroid Build Coastguard Worker //
5886*35ffd701SAndroid Build Coastguard Worker // https://technet.microsoft.com/en-us/subscriptions/yadkxc18(v=vs.90)
_mm_subs_epu8(__m128i a,__m128i b)5887*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_subs_epu8(__m128i a, __m128i b)
5888*35ffd701SAndroid Build Coastguard Worker {
5889*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
5890*35ffd701SAndroid Build Coastguard Worker vqsubq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b)));
5891*35ffd701SAndroid Build Coastguard Worker }
5892*35ffd701SAndroid Build Coastguard Worker
5893*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomieq_sd _mm_comieq_sd
5894*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomige_sd _mm_comige_sd
5895*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomigt_sd _mm_comigt_sd
5896*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomile_sd _mm_comile_sd
5897*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomilt_sd _mm_comilt_sd
5898*35ffd701SAndroid Build Coastguard Worker #define _mm_ucomineq_sd _mm_comineq_sd
5899*35ffd701SAndroid Build Coastguard Worker
5900*35ffd701SAndroid Build Coastguard Worker // Return vector of type __m128d with undefined elements.
5901*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_pd
_mm_undefined_pd(void)5902*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_undefined_pd(void)
5903*35ffd701SAndroid Build Coastguard Worker {
5904*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
5905*35ffd701SAndroid Build Coastguard Worker #pragma GCC diagnostic push
5906*35ffd701SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wuninitialized"
5907*35ffd701SAndroid Build Coastguard Worker #endif
5908*35ffd701SAndroid Build Coastguard Worker __m128d a;
5909*35ffd701SAndroid Build Coastguard Worker return a;
5910*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
5911*35ffd701SAndroid Build Coastguard Worker #pragma GCC diagnostic pop
5912*35ffd701SAndroid Build Coastguard Worker #endif
5913*35ffd701SAndroid Build Coastguard Worker }
5914*35ffd701SAndroid Build Coastguard Worker
5915*35ffd701SAndroid Build Coastguard Worker // Interleaves the upper 4 signed or unsigned 16-bit integers in a with the
5916*35ffd701SAndroid Build Coastguard Worker // upper 4 signed or unsigned 16-bit integers in b.
5917*35ffd701SAndroid Build Coastguard Worker //
5918*35ffd701SAndroid Build Coastguard Worker // r0 := a4
5919*35ffd701SAndroid Build Coastguard Worker // r1 := b4
5920*35ffd701SAndroid Build Coastguard Worker // r2 := a5
5921*35ffd701SAndroid Build Coastguard Worker // r3 := b5
5922*35ffd701SAndroid Build Coastguard Worker // r4 := a6
5923*35ffd701SAndroid Build Coastguard Worker // r5 := b6
5924*35ffd701SAndroid Build Coastguard Worker // r6 := a7
5925*35ffd701SAndroid Build Coastguard Worker // r7 := b7
5926*35ffd701SAndroid Build Coastguard Worker //
5927*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/03196cz7(v=vs.100).aspx
_mm_unpackhi_epi16(__m128i a,__m128i b)5928*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b)
5929*35ffd701SAndroid Build Coastguard Worker {
5930*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5931*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
5932*35ffd701SAndroid Build Coastguard Worker vzip2q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
5933*35ffd701SAndroid Build Coastguard Worker #else
5934*35ffd701SAndroid Build Coastguard Worker int16x4_t a1 = vget_high_s16(vreinterpretq_s16_m128i(a));
5935*35ffd701SAndroid Build Coastguard Worker int16x4_t b1 = vget_high_s16(vreinterpretq_s16_m128i(b));
5936*35ffd701SAndroid Build Coastguard Worker int16x4x2_t result = vzip_s16(a1, b1);
5937*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1]));
5938*35ffd701SAndroid Build Coastguard Worker #endif
5939*35ffd701SAndroid Build Coastguard Worker }
5940*35ffd701SAndroid Build Coastguard Worker
5941*35ffd701SAndroid Build Coastguard Worker // Interleaves the upper 2 signed or unsigned 32-bit integers in a with the
5942*35ffd701SAndroid Build Coastguard Worker // upper 2 signed or unsigned 32-bit integers in b.
5943*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/65sa7cbs(v=vs.100).aspx
_mm_unpackhi_epi32(__m128i a,__m128i b)5944*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b)
5945*35ffd701SAndroid Build Coastguard Worker {
5946*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5947*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
5948*35ffd701SAndroid Build Coastguard Worker vzip2q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
5949*35ffd701SAndroid Build Coastguard Worker #else
5950*35ffd701SAndroid Build Coastguard Worker int32x2_t a1 = vget_high_s32(vreinterpretq_s32_m128i(a));
5951*35ffd701SAndroid Build Coastguard Worker int32x2_t b1 = vget_high_s32(vreinterpretq_s32_m128i(b));
5952*35ffd701SAndroid Build Coastguard Worker int32x2x2_t result = vzip_s32(a1, b1);
5953*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1]));
5954*35ffd701SAndroid Build Coastguard Worker #endif
5955*35ffd701SAndroid Build Coastguard Worker }
5956*35ffd701SAndroid Build Coastguard Worker
5957*35ffd701SAndroid Build Coastguard Worker // Interleaves the upper signed or unsigned 64-bit integer in a with the
5958*35ffd701SAndroid Build Coastguard Worker // upper signed or unsigned 64-bit integer in b.
5959*35ffd701SAndroid Build Coastguard Worker //
5960*35ffd701SAndroid Build Coastguard Worker // r0 := a1
5961*35ffd701SAndroid Build Coastguard Worker // r1 := b1
_mm_unpackhi_epi64(__m128i a,__m128i b)5962*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b)
5963*35ffd701SAndroid Build Coastguard Worker {
5964*35ffd701SAndroid Build Coastguard Worker int64x1_t a_h = vget_high_s64(vreinterpretq_s64_m128i(a));
5965*35ffd701SAndroid Build Coastguard Worker int64x1_t b_h = vget_high_s64(vreinterpretq_s64_m128i(b));
5966*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vcombine_s64(a_h, b_h));
5967*35ffd701SAndroid Build Coastguard Worker }
5968*35ffd701SAndroid Build Coastguard Worker
5969*35ffd701SAndroid Build Coastguard Worker // Interleaves the upper 8 signed or unsigned 8-bit integers in a with the upper
5970*35ffd701SAndroid Build Coastguard Worker // 8 signed or unsigned 8-bit integers in b.
5971*35ffd701SAndroid Build Coastguard Worker //
5972*35ffd701SAndroid Build Coastguard Worker // r0 := a8
5973*35ffd701SAndroid Build Coastguard Worker // r1 := b8
5974*35ffd701SAndroid Build Coastguard Worker // r2 := a9
5975*35ffd701SAndroid Build Coastguard Worker // r3 := b9
5976*35ffd701SAndroid Build Coastguard Worker // ...
5977*35ffd701SAndroid Build Coastguard Worker // r14 := a15
5978*35ffd701SAndroid Build Coastguard Worker // r15 := b15
5979*35ffd701SAndroid Build Coastguard Worker //
5980*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/t5h7783k(v=vs.100).aspx
_mm_unpackhi_epi8(__m128i a,__m128i b)5981*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b)
5982*35ffd701SAndroid Build Coastguard Worker {
5983*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
5984*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
5985*35ffd701SAndroid Build Coastguard Worker vzip2q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
5986*35ffd701SAndroid Build Coastguard Worker #else
5987*35ffd701SAndroid Build Coastguard Worker int8x8_t a1 =
5988*35ffd701SAndroid Build Coastguard Worker vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(a)));
5989*35ffd701SAndroid Build Coastguard Worker int8x8_t b1 =
5990*35ffd701SAndroid Build Coastguard Worker vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(b)));
5991*35ffd701SAndroid Build Coastguard Worker int8x8x2_t result = vzip_s8(a1, b1);
5992*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1]));
5993*35ffd701SAndroid Build Coastguard Worker #endif
5994*35ffd701SAndroid Build Coastguard Worker }
5995*35ffd701SAndroid Build Coastguard Worker
5996*35ffd701SAndroid Build Coastguard Worker // Unpack and interleave double-precision (64-bit) floating-point elements from
5997*35ffd701SAndroid Build Coastguard Worker // the high half of a and b, and store the results in dst.
5998*35ffd701SAndroid Build Coastguard Worker //
5999*35ffd701SAndroid Build Coastguard Worker // DEFINE INTERLEAVE_HIGH_QWORDS(src1[127:0], src2[127:0]) {
6000*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := src1[127:64]
6001*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := src2[127:64]
6002*35ffd701SAndroid Build Coastguard Worker // RETURN dst[127:0]
6003*35ffd701SAndroid Build Coastguard Worker // }
6004*35ffd701SAndroid Build Coastguard Worker // dst[127:0] := INTERLEAVE_HIGH_QWORDS(a[127:0], b[127:0])
6005*35ffd701SAndroid Build Coastguard Worker //
6006*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpackhi_pd
_mm_unpackhi_pd(__m128d a,__m128d b)6007*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_unpackhi_pd(__m128d a, __m128d b)
6008*35ffd701SAndroid Build Coastguard Worker {
6009*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6010*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
6011*35ffd701SAndroid Build Coastguard Worker vzip2q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
6012*35ffd701SAndroid Build Coastguard Worker #else
6013*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(
6014*35ffd701SAndroid Build Coastguard Worker vcombine_s64(vget_high_s64(vreinterpretq_s64_m128d(a)),
6015*35ffd701SAndroid Build Coastguard Worker vget_high_s64(vreinterpretq_s64_m128d(b))));
6016*35ffd701SAndroid Build Coastguard Worker #endif
6017*35ffd701SAndroid Build Coastguard Worker }
6018*35ffd701SAndroid Build Coastguard Worker
6019*35ffd701SAndroid Build Coastguard Worker // Interleaves the lower 4 signed or unsigned 16-bit integers in a with the
6020*35ffd701SAndroid Build Coastguard Worker // lower 4 signed or unsigned 16-bit integers in b.
6021*35ffd701SAndroid Build Coastguard Worker //
6022*35ffd701SAndroid Build Coastguard Worker // r0 := a0
6023*35ffd701SAndroid Build Coastguard Worker // r1 := b0
6024*35ffd701SAndroid Build Coastguard Worker // r2 := a1
6025*35ffd701SAndroid Build Coastguard Worker // r3 := b1
6026*35ffd701SAndroid Build Coastguard Worker // r4 := a2
6027*35ffd701SAndroid Build Coastguard Worker // r5 := b2
6028*35ffd701SAndroid Build Coastguard Worker // r6 := a3
6029*35ffd701SAndroid Build Coastguard Worker // r7 := b3
6030*35ffd701SAndroid Build Coastguard Worker //
6031*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/btxb17bw%28v=vs.90%29.aspx
_mm_unpacklo_epi16(__m128i a,__m128i b)6032*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b)
6033*35ffd701SAndroid Build Coastguard Worker {
6034*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6035*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
6036*35ffd701SAndroid Build Coastguard Worker vzip1q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b)));
6037*35ffd701SAndroid Build Coastguard Worker #else
6038*35ffd701SAndroid Build Coastguard Worker int16x4_t a1 = vget_low_s16(vreinterpretq_s16_m128i(a));
6039*35ffd701SAndroid Build Coastguard Worker int16x4_t b1 = vget_low_s16(vreinterpretq_s16_m128i(b));
6040*35ffd701SAndroid Build Coastguard Worker int16x4x2_t result = vzip_s16(a1, b1);
6041*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1]));
6042*35ffd701SAndroid Build Coastguard Worker #endif
6043*35ffd701SAndroid Build Coastguard Worker }
6044*35ffd701SAndroid Build Coastguard Worker
6045*35ffd701SAndroid Build Coastguard Worker // Interleaves the lower 2 signed or unsigned 32 - bit integers in a with the
6046*35ffd701SAndroid Build Coastguard Worker // lower 2 signed or unsigned 32 - bit integers in b.
6047*35ffd701SAndroid Build Coastguard Worker //
6048*35ffd701SAndroid Build Coastguard Worker // r0 := a0
6049*35ffd701SAndroid Build Coastguard Worker // r1 := b0
6050*35ffd701SAndroid Build Coastguard Worker // r2 := a1
6051*35ffd701SAndroid Build Coastguard Worker // r3 := b1
6052*35ffd701SAndroid Build Coastguard Worker //
6053*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/x8atst9d(v=vs.100).aspx
_mm_unpacklo_epi32(__m128i a,__m128i b)6054*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b)
6055*35ffd701SAndroid Build Coastguard Worker {
6056*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6057*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
6058*35ffd701SAndroid Build Coastguard Worker vzip1q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
6059*35ffd701SAndroid Build Coastguard Worker #else
6060*35ffd701SAndroid Build Coastguard Worker int32x2_t a1 = vget_low_s32(vreinterpretq_s32_m128i(a));
6061*35ffd701SAndroid Build Coastguard Worker int32x2_t b1 = vget_low_s32(vreinterpretq_s32_m128i(b));
6062*35ffd701SAndroid Build Coastguard Worker int32x2x2_t result = vzip_s32(a1, b1);
6063*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1]));
6064*35ffd701SAndroid Build Coastguard Worker #endif
6065*35ffd701SAndroid Build Coastguard Worker }
6066*35ffd701SAndroid Build Coastguard Worker
_mm_unpacklo_epi64(__m128i a,__m128i b)6067*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b)
6068*35ffd701SAndroid Build Coastguard Worker {
6069*35ffd701SAndroid Build Coastguard Worker int64x1_t a_l = vget_low_s64(vreinterpretq_s64_m128i(a));
6070*35ffd701SAndroid Build Coastguard Worker int64x1_t b_l = vget_low_s64(vreinterpretq_s64_m128i(b));
6071*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vcombine_s64(a_l, b_l));
6072*35ffd701SAndroid Build Coastguard Worker }
6073*35ffd701SAndroid Build Coastguard Worker
6074*35ffd701SAndroid Build Coastguard Worker // Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower
6075*35ffd701SAndroid Build Coastguard Worker // 8 signed or unsigned 8-bit integers in b.
6076*35ffd701SAndroid Build Coastguard Worker //
6077*35ffd701SAndroid Build Coastguard Worker // r0 := a0
6078*35ffd701SAndroid Build Coastguard Worker // r1 := b0
6079*35ffd701SAndroid Build Coastguard Worker // r2 := a1
6080*35ffd701SAndroid Build Coastguard Worker // r3 := b1
6081*35ffd701SAndroid Build Coastguard Worker // ...
6082*35ffd701SAndroid Build Coastguard Worker // r14 := a7
6083*35ffd701SAndroid Build Coastguard Worker // r15 := b7
6084*35ffd701SAndroid Build Coastguard Worker //
6085*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/xf7k860c%28v=vs.90%29.aspx
_mm_unpacklo_epi8(__m128i a,__m128i b)6086*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b)
6087*35ffd701SAndroid Build Coastguard Worker {
6088*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6089*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
6090*35ffd701SAndroid Build Coastguard Worker vzip1q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
6091*35ffd701SAndroid Build Coastguard Worker #else
6092*35ffd701SAndroid Build Coastguard Worker int8x8_t a1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(a)));
6093*35ffd701SAndroid Build Coastguard Worker int8x8_t b1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(b)));
6094*35ffd701SAndroid Build Coastguard Worker int8x8x2_t result = vzip_s8(a1, b1);
6095*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1]));
6096*35ffd701SAndroid Build Coastguard Worker #endif
6097*35ffd701SAndroid Build Coastguard Worker }
6098*35ffd701SAndroid Build Coastguard Worker
6099*35ffd701SAndroid Build Coastguard Worker // Unpack and interleave double-precision (64-bit) floating-point elements from
6100*35ffd701SAndroid Build Coastguard Worker // the low half of a and b, and store the results in dst.
6101*35ffd701SAndroid Build Coastguard Worker //
6102*35ffd701SAndroid Build Coastguard Worker // DEFINE INTERLEAVE_QWORDS(src1[127:0], src2[127:0]) {
6103*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := src1[63:0]
6104*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := src2[63:0]
6105*35ffd701SAndroid Build Coastguard Worker // RETURN dst[127:0]
6106*35ffd701SAndroid Build Coastguard Worker // }
6107*35ffd701SAndroid Build Coastguard Worker // dst[127:0] := INTERLEAVE_QWORDS(a[127:0], b[127:0])
6108*35ffd701SAndroid Build Coastguard Worker //
6109*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpacklo_pd
_mm_unpacklo_pd(__m128d a,__m128d b)6110*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_unpacklo_pd(__m128d a, __m128d b)
6111*35ffd701SAndroid Build Coastguard Worker {
6112*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6113*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
6114*35ffd701SAndroid Build Coastguard Worker vzip1q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
6115*35ffd701SAndroid Build Coastguard Worker #else
6116*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(
6117*35ffd701SAndroid Build Coastguard Worker vcombine_s64(vget_low_s64(vreinterpretq_s64_m128d(a)),
6118*35ffd701SAndroid Build Coastguard Worker vget_low_s64(vreinterpretq_s64_m128d(b))));
6119*35ffd701SAndroid Build Coastguard Worker #endif
6120*35ffd701SAndroid Build Coastguard Worker }
6121*35ffd701SAndroid Build Coastguard Worker
6122*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise XOR of packed double-precision (64-bit) floating-point
6123*35ffd701SAndroid Build Coastguard Worker // elements in a and b, and store the results in dst.
6124*35ffd701SAndroid Build Coastguard Worker //
6125*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
6126*35ffd701SAndroid Build Coastguard Worker // i := j*64
6127*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := a[i+63:i] XOR b[i+63:i]
6128*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6129*35ffd701SAndroid Build Coastguard Worker //
6130*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_xor_pd
_mm_xor_pd(__m128d a,__m128d b)6131*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_xor_pd(__m128d a, __m128d b)
6132*35ffd701SAndroid Build Coastguard Worker {
6133*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_s64(
6134*35ffd701SAndroid Build Coastguard Worker veorq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b)));
6135*35ffd701SAndroid Build Coastguard Worker }
6136*35ffd701SAndroid Build Coastguard Worker
6137*35ffd701SAndroid Build Coastguard Worker // Computes the bitwise XOR of the 128-bit value in a and the 128-bit value in
6138*35ffd701SAndroid Build Coastguard Worker // b. https://msdn.microsoft.com/en-us/library/fzt08www(v=vs.100).aspx
_mm_xor_si128(__m128i a,__m128i b)6139*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b)
6140*35ffd701SAndroid Build Coastguard Worker {
6141*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
6142*35ffd701SAndroid Build Coastguard Worker veorq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
6143*35ffd701SAndroid Build Coastguard Worker }
6144*35ffd701SAndroid Build Coastguard Worker
6145*35ffd701SAndroid Build Coastguard Worker /* SSE3 */
6146*35ffd701SAndroid Build Coastguard Worker
6147*35ffd701SAndroid Build Coastguard Worker // Alternatively add and subtract packed double-precision (64-bit)
6148*35ffd701SAndroid Build Coastguard Worker // floating-point elements in a to/from packed elements in b, and store the
6149*35ffd701SAndroid Build Coastguard Worker // results in dst.
6150*35ffd701SAndroid Build Coastguard Worker //
6151*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
6152*35ffd701SAndroid Build Coastguard Worker // i := j*64
6153*35ffd701SAndroid Build Coastguard Worker // IF ((j & 1) == 0)
6154*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := a[i+63:i] - b[i+63:i]
6155*35ffd701SAndroid Build Coastguard Worker // ELSE
6156*35ffd701SAndroid Build Coastguard Worker // dst[i+63:i] := a[i+63:i] + b[i+63:i]
6157*35ffd701SAndroid Build Coastguard Worker // FI
6158*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6159*35ffd701SAndroid Build Coastguard Worker //
6160*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_addsub_pd
_mm_addsub_pd(__m128d a,__m128d b)6161*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_addsub_pd(__m128d a, __m128d b)
6162*35ffd701SAndroid Build Coastguard Worker {
6163*35ffd701SAndroid Build Coastguard Worker __m128d mask = _mm_set_pd(1.0f, -1.0f);
6164*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6165*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vfmaq_f64(vreinterpretq_f64_m128d(a),
6166*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f64_m128d(b),
6167*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f64_m128d(mask)));
6168*35ffd701SAndroid Build Coastguard Worker #else
6169*35ffd701SAndroid Build Coastguard Worker return _mm_add_pd(_mm_mul_pd(b, mask), a);
6170*35ffd701SAndroid Build Coastguard Worker #endif
6171*35ffd701SAndroid Build Coastguard Worker }
6172*35ffd701SAndroid Build Coastguard Worker
6173*35ffd701SAndroid Build Coastguard Worker // Alternatively add and subtract packed single-precision (32-bit)
6174*35ffd701SAndroid Build Coastguard Worker // floating-point elements in a to/from packed elements in b, and store the
6175*35ffd701SAndroid Build Coastguard Worker // results in dst.
6176*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=addsub_ps
_mm_addsub_ps(__m128 a,__m128 b)6177*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_addsub_ps(__m128 a, __m128 b)
6178*35ffd701SAndroid Build Coastguard Worker {
6179*35ffd701SAndroid Build Coastguard Worker __m128 mask = {-1.0f, 1.0f, -1.0f, 1.0f};
6180*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__) || defined(__ARM_FEATURE_FMA) /* VFPv4+ */
6181*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vfmaq_f32(vreinterpretq_f32_m128(a),
6182*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(mask),
6183*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(b)));
6184*35ffd701SAndroid Build Coastguard Worker #else
6185*35ffd701SAndroid Build Coastguard Worker return _mm_add_ps(_mm_mul_ps(b, mask), a);
6186*35ffd701SAndroid Build Coastguard Worker #endif
6187*35ffd701SAndroid Build Coastguard Worker }
6188*35ffd701SAndroid Build Coastguard Worker
6189*35ffd701SAndroid Build Coastguard Worker // Horizontally add adjacent pairs of double-precision (64-bit) floating-point
6190*35ffd701SAndroid Build Coastguard Worker // elements in a and b, and pack the results in dst.
6191*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pd
_mm_hadd_pd(__m128d a,__m128d b)6192*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_hadd_pd(__m128d a, __m128d b)
6193*35ffd701SAndroid Build Coastguard Worker {
6194*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6195*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
6196*35ffd701SAndroid Build Coastguard Worker vpaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)));
6197*35ffd701SAndroid Build Coastguard Worker #else
6198*35ffd701SAndroid Build Coastguard Worker double *da = (double *) &a;
6199*35ffd701SAndroid Build Coastguard Worker double *db = (double *) &b;
6200*35ffd701SAndroid Build Coastguard Worker double c[] = {da[0] + da[1], db[0] + db[1]};
6201*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c));
6202*35ffd701SAndroid Build Coastguard Worker #endif
6203*35ffd701SAndroid Build Coastguard Worker }
6204*35ffd701SAndroid Build Coastguard Worker
6205*35ffd701SAndroid Build Coastguard Worker // Computes pairwise add of each argument as single-precision, floating-point
6206*35ffd701SAndroid Build Coastguard Worker // values a and b.
6207*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/yd9wecaa.aspx
_mm_hadd_ps(__m128 a,__m128 b)6208*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b)
6209*35ffd701SAndroid Build Coastguard Worker {
6210*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6211*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
6212*35ffd701SAndroid Build Coastguard Worker vpaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)));
6213*35ffd701SAndroid Build Coastguard Worker #else
6214*35ffd701SAndroid Build Coastguard Worker float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a));
6215*35ffd701SAndroid Build Coastguard Worker float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a));
6216*35ffd701SAndroid Build Coastguard Worker float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b));
6217*35ffd701SAndroid Build Coastguard Worker float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b));
6218*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
6219*35ffd701SAndroid Build Coastguard Worker vcombine_f32(vpadd_f32(a10, a32), vpadd_f32(b10, b32)));
6220*35ffd701SAndroid Build Coastguard Worker #endif
6221*35ffd701SAndroid Build Coastguard Worker }
6222*35ffd701SAndroid Build Coastguard Worker
6223*35ffd701SAndroid Build Coastguard Worker // Horizontally subtract adjacent pairs of double-precision (64-bit)
6224*35ffd701SAndroid Build Coastguard Worker // floating-point elements in a and b, and pack the results in dst.
6225*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_pd
_mm_hsub_pd(__m128d _a,__m128d _b)6226*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_hsub_pd(__m128d _a, __m128d _b)
6227*35ffd701SAndroid Build Coastguard Worker {
6228*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6229*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vsubq_f64(
6230*35ffd701SAndroid Build Coastguard Worker vuzp1q_f64(vreinterpretq_f64_m128d(_a), vreinterpretq_f64_m128d(_b)),
6231*35ffd701SAndroid Build Coastguard Worker vuzp2q_f64(vreinterpretq_f64_m128d(_a), vreinterpretq_f64_m128d(_b))));
6232*35ffd701SAndroid Build Coastguard Worker #else
6233*35ffd701SAndroid Build Coastguard Worker double *da = (double *) &_a;
6234*35ffd701SAndroid Build Coastguard Worker double *db = (double *) &_b;
6235*35ffd701SAndroid Build Coastguard Worker double c[] = {da[0] - da[1], db[0] - db[1]};
6236*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c));
6237*35ffd701SAndroid Build Coastguard Worker #endif
6238*35ffd701SAndroid Build Coastguard Worker }
6239*35ffd701SAndroid Build Coastguard Worker
6240*35ffd701SAndroid Build Coastguard Worker // Horizontally substract adjacent pairs of single-precision (32-bit)
6241*35ffd701SAndroid Build Coastguard Worker // floating-point elements in a and b, and pack the results in dst.
6242*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_ps
_mm_hsub_ps(__m128 _a,__m128 _b)6243*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_hsub_ps(__m128 _a, __m128 _b)
6244*35ffd701SAndroid Build Coastguard Worker {
6245*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6246*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vsubq_f32(
6247*35ffd701SAndroid Build Coastguard Worker vuzp1q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)),
6248*35ffd701SAndroid Build Coastguard Worker vuzp2q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b))));
6249*35ffd701SAndroid Build Coastguard Worker #else
6250*35ffd701SAndroid Build Coastguard Worker float32x4x2_t c =
6251*35ffd701SAndroid Build Coastguard Worker vuzpq_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b));
6252*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vsubq_f32(c.val[0], c.val[1]));
6253*35ffd701SAndroid Build Coastguard Worker #endif
6254*35ffd701SAndroid Build Coastguard Worker }
6255*35ffd701SAndroid Build Coastguard Worker
6256*35ffd701SAndroid Build Coastguard Worker // Load 128-bits of integer data from unaligned memory into dst. This intrinsic
6257*35ffd701SAndroid Build Coastguard Worker // may perform better than _mm_loadu_si128 when the data crosses a cache line
6258*35ffd701SAndroid Build Coastguard Worker // boundary.
6259*35ffd701SAndroid Build Coastguard Worker //
6260*35ffd701SAndroid Build Coastguard Worker // dst[127:0] := MEM[mem_addr+127:mem_addr]
6261*35ffd701SAndroid Build Coastguard Worker //
6262*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_lddqu_si128
6263*35ffd701SAndroid Build Coastguard Worker #define _mm_lddqu_si128 _mm_loadu_si128
6264*35ffd701SAndroid Build Coastguard Worker
6265*35ffd701SAndroid Build Coastguard Worker // Load a double-precision (64-bit) floating-point element from memory into both
6266*35ffd701SAndroid Build Coastguard Worker // elements of dst.
6267*35ffd701SAndroid Build Coastguard Worker //
6268*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := MEM[mem_addr+63:mem_addr]
6269*35ffd701SAndroid Build Coastguard Worker // dst[127:64] := MEM[mem_addr+63:mem_addr]
6270*35ffd701SAndroid Build Coastguard Worker //
6271*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loaddup_pd
6272*35ffd701SAndroid Build Coastguard Worker #define _mm_loaddup_pd _mm_load1_pd
6273*35ffd701SAndroid Build Coastguard Worker
6274*35ffd701SAndroid Build Coastguard Worker // Duplicate the low double-precision (64-bit) floating-point element from a,
6275*35ffd701SAndroid Build Coastguard Worker // and store the results in dst.
6276*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movedup_pd
_mm_movedup_pd(__m128d a)6277*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_movedup_pd(__m128d a)
6278*35ffd701SAndroid Build Coastguard Worker {
6279*35ffd701SAndroid Build Coastguard Worker #if (__aarch64__)
6280*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(
6281*35ffd701SAndroid Build Coastguard Worker vdupq_laneq_f64(vreinterpretq_f64_m128d(a), 0));
6282*35ffd701SAndroid Build Coastguard Worker #else
6283*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(
6284*35ffd701SAndroid Build Coastguard Worker vdupq_n_u64(vgetq_lane_u64(vreinterpretq_u64_m128d(a), 0)));
6285*35ffd701SAndroid Build Coastguard Worker #endif
6286*35ffd701SAndroid Build Coastguard Worker }
6287*35ffd701SAndroid Build Coastguard Worker
6288*35ffd701SAndroid Build Coastguard Worker // Duplicate odd-indexed single-precision (32-bit) floating-point elements
6289*35ffd701SAndroid Build Coastguard Worker // from a, and store the results in dst.
6290*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movehdup_ps
_mm_movehdup_ps(__m128 a)6291*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_movehdup_ps(__m128 a)
6292*35ffd701SAndroid Build Coastguard Worker {
6293*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_shufflevector)
6294*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(__builtin_shufflevector(
6295*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 1, 1, 3, 3));
6296*35ffd701SAndroid Build Coastguard Worker #else
6297*35ffd701SAndroid Build Coastguard Worker float32_t a1 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 1);
6298*35ffd701SAndroid Build Coastguard Worker float32_t a3 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 3);
6299*35ffd701SAndroid Build Coastguard Worker float ALIGN_STRUCT(16) data[4] = {a1, a1, a3, a3};
6300*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vld1q_f32(data));
6301*35ffd701SAndroid Build Coastguard Worker #endif
6302*35ffd701SAndroid Build Coastguard Worker }
6303*35ffd701SAndroid Build Coastguard Worker
6304*35ffd701SAndroid Build Coastguard Worker // Duplicate even-indexed single-precision (32-bit) floating-point elements
6305*35ffd701SAndroid Build Coastguard Worker // from a, and store the results in dst.
6306*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_moveldup_ps
_mm_moveldup_ps(__m128 a)6307*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_moveldup_ps(__m128 a)
6308*35ffd701SAndroid Build Coastguard Worker {
6309*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_shufflevector)
6310*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(__builtin_shufflevector(
6311*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 0, 0, 2, 2));
6312*35ffd701SAndroid Build Coastguard Worker #else
6313*35ffd701SAndroid Build Coastguard Worker float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0);
6314*35ffd701SAndroid Build Coastguard Worker float32_t a2 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 2);
6315*35ffd701SAndroid Build Coastguard Worker float ALIGN_STRUCT(16) data[4] = {a0, a0, a2, a2};
6316*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vld1q_f32(data));
6317*35ffd701SAndroid Build Coastguard Worker #endif
6318*35ffd701SAndroid Build Coastguard Worker }
6319*35ffd701SAndroid Build Coastguard Worker
6320*35ffd701SAndroid Build Coastguard Worker /* SSSE3 */
6321*35ffd701SAndroid Build Coastguard Worker
6322*35ffd701SAndroid Build Coastguard Worker // Compute the absolute value of packed signed 16-bit integers in a, and store
6323*35ffd701SAndroid Build Coastguard Worker // the unsigned results in dst.
6324*35ffd701SAndroid Build Coastguard Worker //
6325*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
6326*35ffd701SAndroid Build Coastguard Worker // i := j*16
6327*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := ABS(a[i+15:i])
6328*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6329*35ffd701SAndroid Build Coastguard Worker //
6330*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi16
_mm_abs_epi16(__m128i a)6331*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_abs_epi16(__m128i a)
6332*35ffd701SAndroid Build Coastguard Worker {
6333*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vabsq_s16(vreinterpretq_s16_m128i(a)));
6334*35ffd701SAndroid Build Coastguard Worker }
6335*35ffd701SAndroid Build Coastguard Worker
6336*35ffd701SAndroid Build Coastguard Worker // Compute the absolute value of packed signed 32-bit integers in a, and store
6337*35ffd701SAndroid Build Coastguard Worker // the unsigned results in dst.
6338*35ffd701SAndroid Build Coastguard Worker //
6339*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
6340*35ffd701SAndroid Build Coastguard Worker // i := j*32
6341*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := ABS(a[i+31:i])
6342*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6343*35ffd701SAndroid Build Coastguard Worker //
6344*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi32
_mm_abs_epi32(__m128i a)6345*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_abs_epi32(__m128i a)
6346*35ffd701SAndroid Build Coastguard Worker {
6347*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vabsq_s32(vreinterpretq_s32_m128i(a)));
6348*35ffd701SAndroid Build Coastguard Worker }
6349*35ffd701SAndroid Build Coastguard Worker
6350*35ffd701SAndroid Build Coastguard Worker // Compute the absolute value of packed signed 8-bit integers in a, and store
6351*35ffd701SAndroid Build Coastguard Worker // the unsigned results in dst.
6352*35ffd701SAndroid Build Coastguard Worker //
6353*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 15
6354*35ffd701SAndroid Build Coastguard Worker // i := j*8
6355*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := ABS(a[i+7:i])
6356*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6357*35ffd701SAndroid Build Coastguard Worker //
6358*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi8
_mm_abs_epi8(__m128i a)6359*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_abs_epi8(__m128i a)
6360*35ffd701SAndroid Build Coastguard Worker {
6361*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(vabsq_s8(vreinterpretq_s8_m128i(a)));
6362*35ffd701SAndroid Build Coastguard Worker }
6363*35ffd701SAndroid Build Coastguard Worker
6364*35ffd701SAndroid Build Coastguard Worker // Compute the absolute value of packed signed 16-bit integers in a, and store
6365*35ffd701SAndroid Build Coastguard Worker // the unsigned results in dst.
6366*35ffd701SAndroid Build Coastguard Worker //
6367*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
6368*35ffd701SAndroid Build Coastguard Worker // i := j*16
6369*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := ABS(a[i+15:i])
6370*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6371*35ffd701SAndroid Build Coastguard Worker //
6372*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi16
_mm_abs_pi16(__m64 a)6373*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_abs_pi16(__m64 a)
6374*35ffd701SAndroid Build Coastguard Worker {
6375*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s16(vabs_s16(vreinterpret_s16_m64(a)));
6376*35ffd701SAndroid Build Coastguard Worker }
6377*35ffd701SAndroid Build Coastguard Worker
6378*35ffd701SAndroid Build Coastguard Worker // Compute the absolute value of packed signed 32-bit integers in a, and store
6379*35ffd701SAndroid Build Coastguard Worker // the unsigned results in dst.
6380*35ffd701SAndroid Build Coastguard Worker //
6381*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
6382*35ffd701SAndroid Build Coastguard Worker // i := j*32
6383*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := ABS(a[i+31:i])
6384*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6385*35ffd701SAndroid Build Coastguard Worker //
6386*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi32
_mm_abs_pi32(__m64 a)6387*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_abs_pi32(__m64 a)
6388*35ffd701SAndroid Build Coastguard Worker {
6389*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(vabs_s32(vreinterpret_s32_m64(a)));
6390*35ffd701SAndroid Build Coastguard Worker }
6391*35ffd701SAndroid Build Coastguard Worker
6392*35ffd701SAndroid Build Coastguard Worker // Compute the absolute value of packed signed 8-bit integers in a, and store
6393*35ffd701SAndroid Build Coastguard Worker // the unsigned results in dst.
6394*35ffd701SAndroid Build Coastguard Worker //
6395*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
6396*35ffd701SAndroid Build Coastguard Worker // i := j*8
6397*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := ABS(a[i+7:i])
6398*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6399*35ffd701SAndroid Build Coastguard Worker //
6400*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi8
_mm_abs_pi8(__m64 a)6401*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_abs_pi8(__m64 a)
6402*35ffd701SAndroid Build Coastguard Worker {
6403*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s8(vabs_s8(vreinterpret_s8_m64(a)));
6404*35ffd701SAndroid Build Coastguard Worker }
6405*35ffd701SAndroid Build Coastguard Worker
6406*35ffd701SAndroid Build Coastguard Worker // Concatenate 16-byte blocks in a and b into a 32-byte temporary result, shift
6407*35ffd701SAndroid Build Coastguard Worker // the result right by imm8 bytes, and store the low 16 bytes in dst.
6408*35ffd701SAndroid Build Coastguard Worker //
6409*35ffd701SAndroid Build Coastguard Worker // tmp[255:0] := ((a[127:0] << 128)[255:0] OR b[127:0]) >> (imm8*8)
6410*35ffd701SAndroid Build Coastguard Worker // dst[127:0] := tmp[127:0]
6411*35ffd701SAndroid Build Coastguard Worker //
6412*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_epi8
6413*35ffd701SAndroid Build Coastguard Worker #define _mm_alignr_epi8(a, b, imm) \
6414*35ffd701SAndroid Build Coastguard Worker __extension__({ \
6415*35ffd701SAndroid Build Coastguard Worker __m128i ret; \
6416*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) >= 32)) { \
6417*35ffd701SAndroid Build Coastguard Worker ret = _mm_setzero_si128(); \
6418*35ffd701SAndroid Build Coastguard Worker } else { \
6419*35ffd701SAndroid Build Coastguard Worker uint8x16_t tmp_low, tmp_high; \
6420*35ffd701SAndroid Build Coastguard Worker if (imm >= 16) { \
6421*35ffd701SAndroid Build Coastguard Worker const int idx = imm - 16; \
6422*35ffd701SAndroid Build Coastguard Worker tmp_low = vreinterpretq_u8_m128i(a); \
6423*35ffd701SAndroid Build Coastguard Worker tmp_high = vdupq_n_u8(0); \
6424*35ffd701SAndroid Build Coastguard Worker ret = \
6425*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_u8(vextq_u8(tmp_low, tmp_high, idx)); \
6426*35ffd701SAndroid Build Coastguard Worker } else { \
6427*35ffd701SAndroid Build Coastguard Worker const int idx = imm; \
6428*35ffd701SAndroid Build Coastguard Worker tmp_low = vreinterpretq_u8_m128i(b); \
6429*35ffd701SAndroid Build Coastguard Worker tmp_high = vreinterpretq_u8_m128i(a); \
6430*35ffd701SAndroid Build Coastguard Worker ret = \
6431*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_u8(vextq_u8(tmp_low, tmp_high, idx)); \
6432*35ffd701SAndroid Build Coastguard Worker } \
6433*35ffd701SAndroid Build Coastguard Worker } \
6434*35ffd701SAndroid Build Coastguard Worker ret; \
6435*35ffd701SAndroid Build Coastguard Worker })
6436*35ffd701SAndroid Build Coastguard Worker
6437*35ffd701SAndroid Build Coastguard Worker // Concatenate 8-byte blocks in a and b into a 16-byte temporary result, shift
6438*35ffd701SAndroid Build Coastguard Worker // the result right by imm8 bytes, and store the low 8 bytes in dst.
6439*35ffd701SAndroid Build Coastguard Worker //
6440*35ffd701SAndroid Build Coastguard Worker // tmp[127:0] := ((a[63:0] << 64)[127:0] OR b[63:0]) >> (imm8*8)
6441*35ffd701SAndroid Build Coastguard Worker // dst[63:0] := tmp[63:0]
6442*35ffd701SAndroid Build Coastguard Worker //
6443*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_pi8
6444*35ffd701SAndroid Build Coastguard Worker #define _mm_alignr_pi8(a, b, imm) \
6445*35ffd701SAndroid Build Coastguard Worker __extension__({ \
6446*35ffd701SAndroid Build Coastguard Worker __m64 ret; \
6447*35ffd701SAndroid Build Coastguard Worker if (unlikely((imm) >= 16)) { \
6448*35ffd701SAndroid Build Coastguard Worker ret = vreinterpret_m64_s8(vdup_n_s8(0)); \
6449*35ffd701SAndroid Build Coastguard Worker } else { \
6450*35ffd701SAndroid Build Coastguard Worker uint8x8_t tmp_low, tmp_high; \
6451*35ffd701SAndroid Build Coastguard Worker if (imm >= 8) { \
6452*35ffd701SAndroid Build Coastguard Worker const int idx = imm - 8; \
6453*35ffd701SAndroid Build Coastguard Worker tmp_low = vreinterpret_u8_m64(a); \
6454*35ffd701SAndroid Build Coastguard Worker tmp_high = vdup_n_u8(0); \
6455*35ffd701SAndroid Build Coastguard Worker ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \
6456*35ffd701SAndroid Build Coastguard Worker } else { \
6457*35ffd701SAndroid Build Coastguard Worker const int idx = imm; \
6458*35ffd701SAndroid Build Coastguard Worker tmp_low = vreinterpret_u8_m64(b); \
6459*35ffd701SAndroid Build Coastguard Worker tmp_high = vreinterpret_u8_m64(a); \
6460*35ffd701SAndroid Build Coastguard Worker ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \
6461*35ffd701SAndroid Build Coastguard Worker } \
6462*35ffd701SAndroid Build Coastguard Worker } \
6463*35ffd701SAndroid Build Coastguard Worker ret; \
6464*35ffd701SAndroid Build Coastguard Worker })
6465*35ffd701SAndroid Build Coastguard Worker
6466*35ffd701SAndroid Build Coastguard Worker // Computes pairwise add of each argument as a 16-bit signed or unsigned integer
6467*35ffd701SAndroid Build Coastguard Worker // values a and b.
_mm_hadd_epi16(__m128i _a,__m128i _b)6468*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b)
6469*35ffd701SAndroid Build Coastguard Worker {
6470*35ffd701SAndroid Build Coastguard Worker int16x8_t a = vreinterpretq_s16_m128i(_a);
6471*35ffd701SAndroid Build Coastguard Worker int16x8_t b = vreinterpretq_s16_m128i(_b);
6472*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6473*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vpaddq_s16(a, b));
6474*35ffd701SAndroid Build Coastguard Worker #else
6475*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
6476*35ffd701SAndroid Build Coastguard Worker vcombine_s16(vpadd_s16(vget_low_s16(a), vget_high_s16(a)),
6477*35ffd701SAndroid Build Coastguard Worker vpadd_s16(vget_low_s16(b), vget_high_s16(b))));
6478*35ffd701SAndroid Build Coastguard Worker #endif
6479*35ffd701SAndroid Build Coastguard Worker }
6480*35ffd701SAndroid Build Coastguard Worker
6481*35ffd701SAndroid Build Coastguard Worker // Computes pairwise add of each argument as a 32-bit signed or unsigned integer
6482*35ffd701SAndroid Build Coastguard Worker // values a and b.
_mm_hadd_epi32(__m128i _a,__m128i _b)6483*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_hadd_epi32(__m128i _a, __m128i _b)
6484*35ffd701SAndroid Build Coastguard Worker {
6485*35ffd701SAndroid Build Coastguard Worker int32x4_t a = vreinterpretq_s32_m128i(_a);
6486*35ffd701SAndroid Build Coastguard Worker int32x4_t b = vreinterpretq_s32_m128i(_b);
6487*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
6488*35ffd701SAndroid Build Coastguard Worker vcombine_s32(vpadd_s32(vget_low_s32(a), vget_high_s32(a)),
6489*35ffd701SAndroid Build Coastguard Worker vpadd_s32(vget_low_s32(b), vget_high_s32(b))));
6490*35ffd701SAndroid Build Coastguard Worker }
6491*35ffd701SAndroid Build Coastguard Worker
6492*35ffd701SAndroid Build Coastguard Worker // Horizontally add adjacent pairs of 16-bit integers in a and b, and pack the
6493*35ffd701SAndroid Build Coastguard Worker // signed 16-bit results in dst.
6494*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi16
_mm_hadd_pi16(__m64 a,__m64 b)6495*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_hadd_pi16(__m64 a, __m64 b)
6496*35ffd701SAndroid Build Coastguard Worker {
6497*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s16(
6498*35ffd701SAndroid Build Coastguard Worker vpadd_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b)));
6499*35ffd701SAndroid Build Coastguard Worker }
6500*35ffd701SAndroid Build Coastguard Worker
6501*35ffd701SAndroid Build Coastguard Worker // Horizontally add adjacent pairs of 32-bit integers in a and b, and pack the
6502*35ffd701SAndroid Build Coastguard Worker // signed 32-bit results in dst.
6503*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi32
_mm_hadd_pi32(__m64 a,__m64 b)6504*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_hadd_pi32(__m64 a, __m64 b)
6505*35ffd701SAndroid Build Coastguard Worker {
6506*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(
6507*35ffd701SAndroid Build Coastguard Worker vpadd_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b)));
6508*35ffd701SAndroid Build Coastguard Worker }
6509*35ffd701SAndroid Build Coastguard Worker
6510*35ffd701SAndroid Build Coastguard Worker // Computes saturated pairwise sub of each argument as a 16-bit signed
6511*35ffd701SAndroid Build Coastguard Worker // integer values a and b.
_mm_hadds_epi16(__m128i _a,__m128i _b)6512*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_hadds_epi16(__m128i _a, __m128i _b)
6513*35ffd701SAndroid Build Coastguard Worker {
6514*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6515*35ffd701SAndroid Build Coastguard Worker int16x8_t a = vreinterpretq_s16_m128i(_a);
6516*35ffd701SAndroid Build Coastguard Worker int16x8_t b = vreinterpretq_s16_m128i(_b);
6517*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_s64_s16(
6518*35ffd701SAndroid Build Coastguard Worker vqaddq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b)));
6519*35ffd701SAndroid Build Coastguard Worker #else
6520*35ffd701SAndroid Build Coastguard Worker int32x4_t a = vreinterpretq_s32_m128i(_a);
6521*35ffd701SAndroid Build Coastguard Worker int32x4_t b = vreinterpretq_s32_m128i(_b);
6522*35ffd701SAndroid Build Coastguard Worker // Interleave using vshrn/vmovn
6523*35ffd701SAndroid Build Coastguard Worker // [a0|a2|a4|a6|b0|b2|b4|b6]
6524*35ffd701SAndroid Build Coastguard Worker // [a1|a3|a5|a7|b1|b3|b5|b7]
6525*35ffd701SAndroid Build Coastguard Worker int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b));
6526*35ffd701SAndroid Build Coastguard Worker int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16));
6527*35ffd701SAndroid Build Coastguard Worker // Saturated add
6528*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vqaddq_s16(ab0246, ab1357));
6529*35ffd701SAndroid Build Coastguard Worker #endif
6530*35ffd701SAndroid Build Coastguard Worker }
6531*35ffd701SAndroid Build Coastguard Worker
6532*35ffd701SAndroid Build Coastguard Worker // Horizontally add adjacent pairs of signed 16-bit integers in a and b using
6533*35ffd701SAndroid Build Coastguard Worker // saturation, and pack the signed 16-bit results in dst.
6534*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadds_pi16
_mm_hadds_pi16(__m64 _a,__m64 _b)6535*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_hadds_pi16(__m64 _a, __m64 _b)
6536*35ffd701SAndroid Build Coastguard Worker {
6537*35ffd701SAndroid Build Coastguard Worker int16x4_t a = vreinterpret_s16_m64(_a);
6538*35ffd701SAndroid Build Coastguard Worker int16x4_t b = vreinterpret_s16_m64(_b);
6539*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6540*35ffd701SAndroid Build Coastguard Worker return vreinterpret_s64_s16(vqadd_s16(vuzp1_s16(a, b), vuzp2_s16(a, b)));
6541*35ffd701SAndroid Build Coastguard Worker #else
6542*35ffd701SAndroid Build Coastguard Worker int16x4x2_t res = vuzp_s16(a, b);
6543*35ffd701SAndroid Build Coastguard Worker return vreinterpret_s64_s16(vqadd_s16(res.val[0], res.val[1]));
6544*35ffd701SAndroid Build Coastguard Worker #endif
6545*35ffd701SAndroid Build Coastguard Worker }
6546*35ffd701SAndroid Build Coastguard Worker
6547*35ffd701SAndroid Build Coastguard Worker // Computes pairwise difference of each argument as a 16-bit signed or unsigned
6548*35ffd701SAndroid Build Coastguard Worker // integer values a and b.
_mm_hsub_epi16(__m128i _a,__m128i _b)6549*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_hsub_epi16(__m128i _a, __m128i _b)
6550*35ffd701SAndroid Build Coastguard Worker {
6551*35ffd701SAndroid Build Coastguard Worker int32x4_t a = vreinterpretq_s32_m128i(_a);
6552*35ffd701SAndroid Build Coastguard Worker int32x4_t b = vreinterpretq_s32_m128i(_b);
6553*35ffd701SAndroid Build Coastguard Worker // Interleave using vshrn/vmovn
6554*35ffd701SAndroid Build Coastguard Worker // [a0|a2|a4|a6|b0|b2|b4|b6]
6555*35ffd701SAndroid Build Coastguard Worker // [a1|a3|a5|a7|b1|b3|b5|b7]
6556*35ffd701SAndroid Build Coastguard Worker int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b));
6557*35ffd701SAndroid Build Coastguard Worker int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16));
6558*35ffd701SAndroid Build Coastguard Worker // Subtract
6559*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vsubq_s16(ab0246, ab1357));
6560*35ffd701SAndroid Build Coastguard Worker }
6561*35ffd701SAndroid Build Coastguard Worker
6562*35ffd701SAndroid Build Coastguard Worker // Computes pairwise difference of each argument as a 32-bit signed or unsigned
6563*35ffd701SAndroid Build Coastguard Worker // integer values a and b.
_mm_hsub_epi32(__m128i _a,__m128i _b)6564*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_hsub_epi32(__m128i _a, __m128i _b)
6565*35ffd701SAndroid Build Coastguard Worker {
6566*35ffd701SAndroid Build Coastguard Worker int64x2_t a = vreinterpretq_s64_m128i(_a);
6567*35ffd701SAndroid Build Coastguard Worker int64x2_t b = vreinterpretq_s64_m128i(_b);
6568*35ffd701SAndroid Build Coastguard Worker // Interleave using vshrn/vmovn
6569*35ffd701SAndroid Build Coastguard Worker // [a0|a2|b0|b2]
6570*35ffd701SAndroid Build Coastguard Worker // [a1|a2|b1|b3]
6571*35ffd701SAndroid Build Coastguard Worker int32x4_t ab02 = vcombine_s32(vmovn_s64(a), vmovn_s64(b));
6572*35ffd701SAndroid Build Coastguard Worker int32x4_t ab13 = vcombine_s32(vshrn_n_s64(a, 32), vshrn_n_s64(b, 32));
6573*35ffd701SAndroid Build Coastguard Worker // Subtract
6574*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(vsubq_s32(ab02, ab13));
6575*35ffd701SAndroid Build Coastguard Worker }
6576*35ffd701SAndroid Build Coastguard Worker
6577*35ffd701SAndroid Build Coastguard Worker // Horizontally subtract adjacent pairs of 16-bit integers in a and b, and pack
6578*35ffd701SAndroid Build Coastguard Worker // the signed 16-bit results in dst.
6579*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_pi16
_mm_hsub_pi16(__m64 _a,__m64 _b)6580*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_hsub_pi16(__m64 _a, __m64 _b)
6581*35ffd701SAndroid Build Coastguard Worker {
6582*35ffd701SAndroid Build Coastguard Worker int32x4_t ab =
6583*35ffd701SAndroid Build Coastguard Worker vcombine_s32(vreinterpret_s32_m64(_a), vreinterpret_s32_m64(_b));
6584*35ffd701SAndroid Build Coastguard Worker
6585*35ffd701SAndroid Build Coastguard Worker int16x4_t ab_low_bits = vmovn_s32(ab);
6586*35ffd701SAndroid Build Coastguard Worker int16x4_t ab_high_bits = vshrn_n_s32(ab, 16);
6587*35ffd701SAndroid Build Coastguard Worker
6588*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s16(vsub_s16(ab_low_bits, ab_high_bits));
6589*35ffd701SAndroid Build Coastguard Worker }
6590*35ffd701SAndroid Build Coastguard Worker
6591*35ffd701SAndroid Build Coastguard Worker // Horizontally subtract adjacent pairs of 32-bit integers in a and b, and pack
6592*35ffd701SAndroid Build Coastguard Worker // the signed 32-bit results in dst.
6593*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_hsub_pi32
_mm_hsub_pi32(__m64 _a,__m64 _b)6594*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_hsub_pi32(__m64 _a, __m64 _b)
6595*35ffd701SAndroid Build Coastguard Worker {
6596*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6597*35ffd701SAndroid Build Coastguard Worker int32x2_t a = vreinterpret_s32_m64(_a);
6598*35ffd701SAndroid Build Coastguard Worker int32x2_t b = vreinterpret_s32_m64(_b);
6599*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(vsub_s32(vtrn1_s32(a, b), vtrn2_s32(a, b)));
6600*35ffd701SAndroid Build Coastguard Worker #else
6601*35ffd701SAndroid Build Coastguard Worker int32x2x2_t trn_ab =
6602*35ffd701SAndroid Build Coastguard Worker vtrn_s32(vreinterpret_s32_m64(_a), vreinterpret_s32_m64(_b));
6603*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(vsub_s32(trn_ab.val[0], trn_ab.val[1]));
6604*35ffd701SAndroid Build Coastguard Worker #endif
6605*35ffd701SAndroid Build Coastguard Worker }
6606*35ffd701SAndroid Build Coastguard Worker
6607*35ffd701SAndroid Build Coastguard Worker // Computes saturated pairwise difference of each argument as a 16-bit signed
6608*35ffd701SAndroid Build Coastguard Worker // integer values a and b.
6609*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_epi16
_mm_hsubs_epi16(__m128i _a,__m128i _b)6610*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_hsubs_epi16(__m128i _a, __m128i _b)
6611*35ffd701SAndroid Build Coastguard Worker {
6612*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6613*35ffd701SAndroid Build Coastguard Worker int16x8_t a = vreinterpretq_s16_m128i(_a);
6614*35ffd701SAndroid Build Coastguard Worker int16x8_t b = vreinterpretq_s16_m128i(_b);
6615*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_s64_s16(
6616*35ffd701SAndroid Build Coastguard Worker vqsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b)));
6617*35ffd701SAndroid Build Coastguard Worker #else
6618*35ffd701SAndroid Build Coastguard Worker int32x4_t a = vreinterpretq_s32_m128i(_a);
6619*35ffd701SAndroid Build Coastguard Worker int32x4_t b = vreinterpretq_s32_m128i(_b);
6620*35ffd701SAndroid Build Coastguard Worker // Interleave using vshrn/vmovn
6621*35ffd701SAndroid Build Coastguard Worker // [a0|a2|a4|a6|b0|b2|b4|b6]
6622*35ffd701SAndroid Build Coastguard Worker // [a1|a3|a5|a7|b1|b3|b5|b7]
6623*35ffd701SAndroid Build Coastguard Worker int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b));
6624*35ffd701SAndroid Build Coastguard Worker int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16));
6625*35ffd701SAndroid Build Coastguard Worker // Saturated subtract
6626*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vqsubq_s16(ab0246, ab1357));
6627*35ffd701SAndroid Build Coastguard Worker #endif
6628*35ffd701SAndroid Build Coastguard Worker }
6629*35ffd701SAndroid Build Coastguard Worker
6630*35ffd701SAndroid Build Coastguard Worker // Horizontally subtract adjacent pairs of signed 16-bit integers in a and b
6631*35ffd701SAndroid Build Coastguard Worker // using saturation, and pack the signed 16-bit results in dst.
6632*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_pi16
_mm_hsubs_pi16(__m64 _a,__m64 _b)6633*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_hsubs_pi16(__m64 _a, __m64 _b)
6634*35ffd701SAndroid Build Coastguard Worker {
6635*35ffd701SAndroid Build Coastguard Worker int16x4_t a = vreinterpret_s16_m64(_a);
6636*35ffd701SAndroid Build Coastguard Worker int16x4_t b = vreinterpret_s16_m64(_b);
6637*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6638*35ffd701SAndroid Build Coastguard Worker return vreinterpret_s64_s16(vqsub_s16(vuzp1_s16(a, b), vuzp2_s16(a, b)));
6639*35ffd701SAndroid Build Coastguard Worker #else
6640*35ffd701SAndroid Build Coastguard Worker int16x4x2_t res = vuzp_s16(a, b);
6641*35ffd701SAndroid Build Coastguard Worker return vreinterpret_s64_s16(vqsub_s16(res.val[0], res.val[1]));
6642*35ffd701SAndroid Build Coastguard Worker #endif
6643*35ffd701SAndroid Build Coastguard Worker }
6644*35ffd701SAndroid Build Coastguard Worker
6645*35ffd701SAndroid Build Coastguard Worker // Vertically multiply each unsigned 8-bit integer from a with the corresponding
6646*35ffd701SAndroid Build Coastguard Worker // signed 8-bit integer from b, producing intermediate signed 16-bit integers.
6647*35ffd701SAndroid Build Coastguard Worker // Horizontally add adjacent pairs of intermediate signed 16-bit integers,
6648*35ffd701SAndroid Build Coastguard Worker // and pack the saturated results in dst.
6649*35ffd701SAndroid Build Coastguard Worker //
6650*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
6651*35ffd701SAndroid Build Coastguard Worker // i := j*16
6652*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := Saturate_To_Int16( a[i+15:i+8]*b[i+15:i+8] +
6653*35ffd701SAndroid Build Coastguard Worker // a[i+7:i]*b[i+7:i] )
6654*35ffd701SAndroid Build Coastguard Worker // ENDFOR
_mm_maddubs_epi16(__m128i _a,__m128i _b)6655*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_maddubs_epi16(__m128i _a, __m128i _b)
6656*35ffd701SAndroid Build Coastguard Worker {
6657*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6658*35ffd701SAndroid Build Coastguard Worker uint8x16_t a = vreinterpretq_u8_m128i(_a);
6659*35ffd701SAndroid Build Coastguard Worker int8x16_t b = vreinterpretq_s8_m128i(_b);
6660*35ffd701SAndroid Build Coastguard Worker int16x8_t tl = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(a))),
6661*35ffd701SAndroid Build Coastguard Worker vmovl_s8(vget_low_s8(b)));
6662*35ffd701SAndroid Build Coastguard Worker int16x8_t th = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(a))),
6663*35ffd701SAndroid Build Coastguard Worker vmovl_s8(vget_high_s8(b)));
6664*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(
6665*35ffd701SAndroid Build Coastguard Worker vqaddq_s16(vuzp1q_s16(tl, th), vuzp2q_s16(tl, th)));
6666*35ffd701SAndroid Build Coastguard Worker #else
6667*35ffd701SAndroid Build Coastguard Worker // This would be much simpler if x86 would choose to zero extend OR sign
6668*35ffd701SAndroid Build Coastguard Worker // extend, not both. This could probably be optimized better.
6669*35ffd701SAndroid Build Coastguard Worker uint16x8_t a = vreinterpretq_u16_m128i(_a);
6670*35ffd701SAndroid Build Coastguard Worker int16x8_t b = vreinterpretq_s16_m128i(_b);
6671*35ffd701SAndroid Build Coastguard Worker
6672*35ffd701SAndroid Build Coastguard Worker // Zero extend a
6673*35ffd701SAndroid Build Coastguard Worker int16x8_t a_odd = vreinterpretq_s16_u16(vshrq_n_u16(a, 8));
6674*35ffd701SAndroid Build Coastguard Worker int16x8_t a_even = vreinterpretq_s16_u16(vbicq_u16(a, vdupq_n_u16(0xff00)));
6675*35ffd701SAndroid Build Coastguard Worker
6676*35ffd701SAndroid Build Coastguard Worker // Sign extend by shifting left then shifting right.
6677*35ffd701SAndroid Build Coastguard Worker int16x8_t b_even = vshrq_n_s16(vshlq_n_s16(b, 8), 8);
6678*35ffd701SAndroid Build Coastguard Worker int16x8_t b_odd = vshrq_n_s16(b, 8);
6679*35ffd701SAndroid Build Coastguard Worker
6680*35ffd701SAndroid Build Coastguard Worker // multiply
6681*35ffd701SAndroid Build Coastguard Worker int16x8_t prod1 = vmulq_s16(a_even, b_even);
6682*35ffd701SAndroid Build Coastguard Worker int16x8_t prod2 = vmulq_s16(a_odd, b_odd);
6683*35ffd701SAndroid Build Coastguard Worker
6684*35ffd701SAndroid Build Coastguard Worker // saturated add
6685*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vqaddq_s16(prod1, prod2));
6686*35ffd701SAndroid Build Coastguard Worker #endif
6687*35ffd701SAndroid Build Coastguard Worker }
6688*35ffd701SAndroid Build Coastguard Worker
6689*35ffd701SAndroid Build Coastguard Worker // Vertically multiply each unsigned 8-bit integer from a with the corresponding
6690*35ffd701SAndroid Build Coastguard Worker // signed 8-bit integer from b, producing intermediate signed 16-bit integers.
6691*35ffd701SAndroid Build Coastguard Worker // Horizontally add adjacent pairs of intermediate signed 16-bit integers, and
6692*35ffd701SAndroid Build Coastguard Worker // pack the saturated results in dst.
6693*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maddubs_pi16
_mm_maddubs_pi16(__m64 _a,__m64 _b)6694*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_maddubs_pi16(__m64 _a, __m64 _b)
6695*35ffd701SAndroid Build Coastguard Worker {
6696*35ffd701SAndroid Build Coastguard Worker uint16x4_t a = vreinterpret_u16_m64(_a);
6697*35ffd701SAndroid Build Coastguard Worker int16x4_t b = vreinterpret_s16_m64(_b);
6698*35ffd701SAndroid Build Coastguard Worker
6699*35ffd701SAndroid Build Coastguard Worker // Zero extend a
6700*35ffd701SAndroid Build Coastguard Worker int16x4_t a_odd = vreinterpret_s16_u16(vshr_n_u16(a, 8));
6701*35ffd701SAndroid Build Coastguard Worker int16x4_t a_even = vreinterpret_s16_u16(vand_u16(a, vdup_n_u16(0xff)));
6702*35ffd701SAndroid Build Coastguard Worker
6703*35ffd701SAndroid Build Coastguard Worker // Sign extend by shifting left then shifting right.
6704*35ffd701SAndroid Build Coastguard Worker int16x4_t b_even = vshr_n_s16(vshl_n_s16(b, 8), 8);
6705*35ffd701SAndroid Build Coastguard Worker int16x4_t b_odd = vshr_n_s16(b, 8);
6706*35ffd701SAndroid Build Coastguard Worker
6707*35ffd701SAndroid Build Coastguard Worker // multiply
6708*35ffd701SAndroid Build Coastguard Worker int16x4_t prod1 = vmul_s16(a_even, b_even);
6709*35ffd701SAndroid Build Coastguard Worker int16x4_t prod2 = vmul_s16(a_odd, b_odd);
6710*35ffd701SAndroid Build Coastguard Worker
6711*35ffd701SAndroid Build Coastguard Worker // saturated add
6712*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s16(vqadd_s16(prod1, prod2));
6713*35ffd701SAndroid Build Coastguard Worker }
6714*35ffd701SAndroid Build Coastguard Worker
6715*35ffd701SAndroid Build Coastguard Worker // Multiply packed signed 16-bit integers in a and b, producing intermediate
6716*35ffd701SAndroid Build Coastguard Worker // signed 32-bit integers. Shift right by 15 bits while rounding up, and store
6717*35ffd701SAndroid Build Coastguard Worker // the packed 16-bit integers in dst.
6718*35ffd701SAndroid Build Coastguard Worker //
6719*35ffd701SAndroid Build Coastguard Worker // r0 := Round(((int32_t)a0 * (int32_t)b0) >> 15)
6720*35ffd701SAndroid Build Coastguard Worker // r1 := Round(((int32_t)a1 * (int32_t)b1) >> 15)
6721*35ffd701SAndroid Build Coastguard Worker // r2 := Round(((int32_t)a2 * (int32_t)b2) >> 15)
6722*35ffd701SAndroid Build Coastguard Worker // ...
6723*35ffd701SAndroid Build Coastguard Worker // r7 := Round(((int32_t)a7 * (int32_t)b7) >> 15)
_mm_mulhrs_epi16(__m128i a,__m128i b)6724*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_mulhrs_epi16(__m128i a, __m128i b)
6725*35ffd701SAndroid Build Coastguard Worker {
6726*35ffd701SAndroid Build Coastguard Worker // Has issues due to saturation
6727*35ffd701SAndroid Build Coastguard Worker // return vreinterpretq_m128i_s16(vqrdmulhq_s16(a, b));
6728*35ffd701SAndroid Build Coastguard Worker
6729*35ffd701SAndroid Build Coastguard Worker // Multiply
6730*35ffd701SAndroid Build Coastguard Worker int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)),
6731*35ffd701SAndroid Build Coastguard Worker vget_low_s16(vreinterpretq_s16_m128i(b)));
6732*35ffd701SAndroid Build Coastguard Worker int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)),
6733*35ffd701SAndroid Build Coastguard Worker vget_high_s16(vreinterpretq_s16_m128i(b)));
6734*35ffd701SAndroid Build Coastguard Worker
6735*35ffd701SAndroid Build Coastguard Worker // Rounding narrowing shift right
6736*35ffd701SAndroid Build Coastguard Worker // narrow = (int16_t)((mul + 16384) >> 15);
6737*35ffd701SAndroid Build Coastguard Worker int16x4_t narrow_lo = vrshrn_n_s32(mul_lo, 15);
6738*35ffd701SAndroid Build Coastguard Worker int16x4_t narrow_hi = vrshrn_n_s32(mul_hi, 15);
6739*35ffd701SAndroid Build Coastguard Worker
6740*35ffd701SAndroid Build Coastguard Worker // Join together
6741*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(vcombine_s16(narrow_lo, narrow_hi));
6742*35ffd701SAndroid Build Coastguard Worker }
6743*35ffd701SAndroid Build Coastguard Worker
6744*35ffd701SAndroid Build Coastguard Worker // Multiply packed signed 16-bit integers in a and b, producing intermediate
6745*35ffd701SAndroid Build Coastguard Worker // signed 32-bit integers. Truncate each intermediate integer to the 18 most
6746*35ffd701SAndroid Build Coastguard Worker // significant bits, round by adding 1, and store bits [16:1] to dst.
6747*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhrs_pi16
_mm_mulhrs_pi16(__m64 a,__m64 b)6748*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_mulhrs_pi16(__m64 a, __m64 b)
6749*35ffd701SAndroid Build Coastguard Worker {
6750*35ffd701SAndroid Build Coastguard Worker int32x4_t mul_extend =
6751*35ffd701SAndroid Build Coastguard Worker vmull_s16((vreinterpret_s16_m64(a)), (vreinterpret_s16_m64(b)));
6752*35ffd701SAndroid Build Coastguard Worker
6753*35ffd701SAndroid Build Coastguard Worker // Rounding narrowing shift right
6754*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s16(vrshrn_n_s32(mul_extend, 15));
6755*35ffd701SAndroid Build Coastguard Worker }
6756*35ffd701SAndroid Build Coastguard Worker
6757*35ffd701SAndroid Build Coastguard Worker // Shuffle packed 8-bit integers in a according to shuffle control mask in the
6758*35ffd701SAndroid Build Coastguard Worker // corresponding 8-bit element of b, and store the results in dst.
6759*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_epi8
_mm_shuffle_epi8(__m128i a,__m128i b)6760*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b)
6761*35ffd701SAndroid Build Coastguard Worker {
6762*35ffd701SAndroid Build Coastguard Worker int8x16_t tbl = vreinterpretq_s8_m128i(a); // input a
6763*35ffd701SAndroid Build Coastguard Worker uint8x16_t idx = vreinterpretq_u8_m128i(b); // input b
6764*35ffd701SAndroid Build Coastguard Worker uint8x16_t idx_masked =
6765*35ffd701SAndroid Build Coastguard Worker vandq_u8(idx, vdupq_n_u8(0x8F)); // avoid using meaningless bits
6766*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6767*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(vqtbl1q_s8(tbl, idx_masked));
6768*35ffd701SAndroid Build Coastguard Worker #elif defined(__GNUC__)
6769*35ffd701SAndroid Build Coastguard Worker int8x16_t ret;
6770*35ffd701SAndroid Build Coastguard Worker // %e and %f represent the even and odd D registers
6771*35ffd701SAndroid Build Coastguard Worker // respectively.
6772*35ffd701SAndroid Build Coastguard Worker __asm__ __volatile__(
6773*35ffd701SAndroid Build Coastguard Worker "vtbl.8 %e[ret], {%e[tbl], %f[tbl]}, %e[idx]\n"
6774*35ffd701SAndroid Build Coastguard Worker "vtbl.8 %f[ret], {%e[tbl], %f[tbl]}, %f[idx]\n"
6775*35ffd701SAndroid Build Coastguard Worker : [ret] "=&w"(ret)
6776*35ffd701SAndroid Build Coastguard Worker : [tbl] "w"(tbl), [idx] "w"(idx_masked));
6777*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(ret);
6778*35ffd701SAndroid Build Coastguard Worker #else
6779*35ffd701SAndroid Build Coastguard Worker // use this line if testing on aarch64
6780*35ffd701SAndroid Build Coastguard Worker int8x8x2_t a_split = {vget_low_s8(tbl), vget_high_s8(tbl)};
6781*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
6782*35ffd701SAndroid Build Coastguard Worker vcombine_s8(vtbl2_s8(a_split, vget_low_u8(idx_masked)),
6783*35ffd701SAndroid Build Coastguard Worker vtbl2_s8(a_split, vget_high_u8(idx_masked))));
6784*35ffd701SAndroid Build Coastguard Worker #endif
6785*35ffd701SAndroid Build Coastguard Worker }
6786*35ffd701SAndroid Build Coastguard Worker
6787*35ffd701SAndroid Build Coastguard Worker // Negate packed 16-bit integers in a when the corresponding signed
6788*35ffd701SAndroid Build Coastguard Worker // 16-bit integer in b is negative, and store the results in dst.
6789*35ffd701SAndroid Build Coastguard Worker // Element in dst are zeroed out when the corresponding element
6790*35ffd701SAndroid Build Coastguard Worker // in b is zero.
6791*35ffd701SAndroid Build Coastguard Worker //
6792*35ffd701SAndroid Build Coastguard Worker // for i in 0..7
6793*35ffd701SAndroid Build Coastguard Worker // if b[i] < 0
6794*35ffd701SAndroid Build Coastguard Worker // r[i] := -a[i]
6795*35ffd701SAndroid Build Coastguard Worker // else if b[i] == 0
6796*35ffd701SAndroid Build Coastguard Worker // r[i] := 0
6797*35ffd701SAndroid Build Coastguard Worker // else
6798*35ffd701SAndroid Build Coastguard Worker // r[i] := a[i]
6799*35ffd701SAndroid Build Coastguard Worker // fi
6800*35ffd701SAndroid Build Coastguard Worker // done
_mm_sign_epi16(__m128i _a,__m128i _b)6801*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sign_epi16(__m128i _a, __m128i _b)
6802*35ffd701SAndroid Build Coastguard Worker {
6803*35ffd701SAndroid Build Coastguard Worker int16x8_t a = vreinterpretq_s16_m128i(_a);
6804*35ffd701SAndroid Build Coastguard Worker int16x8_t b = vreinterpretq_s16_m128i(_b);
6805*35ffd701SAndroid Build Coastguard Worker
6806*35ffd701SAndroid Build Coastguard Worker // signed shift right: faster than vclt
6807*35ffd701SAndroid Build Coastguard Worker // (b < 0) ? 0xFFFF : 0
6808*35ffd701SAndroid Build Coastguard Worker uint16x8_t ltMask = vreinterpretq_u16_s16(vshrq_n_s16(b, 15));
6809*35ffd701SAndroid Build Coastguard Worker // (b == 0) ? 0xFFFF : 0
6810*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6811*35ffd701SAndroid Build Coastguard Worker int16x8_t zeroMask = vreinterpretq_s16_u16(vceqzq_s16(b));
6812*35ffd701SAndroid Build Coastguard Worker #else
6813*35ffd701SAndroid Build Coastguard Worker int16x8_t zeroMask = vreinterpretq_s16_u16(vceqq_s16(b, vdupq_n_s16(0)));
6814*35ffd701SAndroid Build Coastguard Worker #endif
6815*35ffd701SAndroid Build Coastguard Worker
6816*35ffd701SAndroid Build Coastguard Worker // bitwise select either a or negative 'a' (vnegq_s16(a) equals to negative
6817*35ffd701SAndroid Build Coastguard Worker // 'a') based on ltMask
6818*35ffd701SAndroid Build Coastguard Worker int16x8_t masked = vbslq_s16(ltMask, vnegq_s16(a), a);
6819*35ffd701SAndroid Build Coastguard Worker // res = masked & (~zeroMask)
6820*35ffd701SAndroid Build Coastguard Worker int16x8_t res = vbicq_s16(masked, zeroMask);
6821*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(res);
6822*35ffd701SAndroid Build Coastguard Worker }
6823*35ffd701SAndroid Build Coastguard Worker
6824*35ffd701SAndroid Build Coastguard Worker // Negate packed 32-bit integers in a when the corresponding signed
6825*35ffd701SAndroid Build Coastguard Worker // 32-bit integer in b is negative, and store the results in dst.
6826*35ffd701SAndroid Build Coastguard Worker // Element in dst are zeroed out when the corresponding element
6827*35ffd701SAndroid Build Coastguard Worker // in b is zero.
6828*35ffd701SAndroid Build Coastguard Worker //
6829*35ffd701SAndroid Build Coastguard Worker // for i in 0..3
6830*35ffd701SAndroid Build Coastguard Worker // if b[i] < 0
6831*35ffd701SAndroid Build Coastguard Worker // r[i] := -a[i]
6832*35ffd701SAndroid Build Coastguard Worker // else if b[i] == 0
6833*35ffd701SAndroid Build Coastguard Worker // r[i] := 0
6834*35ffd701SAndroid Build Coastguard Worker // else
6835*35ffd701SAndroid Build Coastguard Worker // r[i] := a[i]
6836*35ffd701SAndroid Build Coastguard Worker // fi
6837*35ffd701SAndroid Build Coastguard Worker // done
_mm_sign_epi32(__m128i _a,__m128i _b)6838*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sign_epi32(__m128i _a, __m128i _b)
6839*35ffd701SAndroid Build Coastguard Worker {
6840*35ffd701SAndroid Build Coastguard Worker int32x4_t a = vreinterpretq_s32_m128i(_a);
6841*35ffd701SAndroid Build Coastguard Worker int32x4_t b = vreinterpretq_s32_m128i(_b);
6842*35ffd701SAndroid Build Coastguard Worker
6843*35ffd701SAndroid Build Coastguard Worker // signed shift right: faster than vclt
6844*35ffd701SAndroid Build Coastguard Worker // (b < 0) ? 0xFFFFFFFF : 0
6845*35ffd701SAndroid Build Coastguard Worker uint32x4_t ltMask = vreinterpretq_u32_s32(vshrq_n_s32(b, 31));
6846*35ffd701SAndroid Build Coastguard Worker
6847*35ffd701SAndroid Build Coastguard Worker // (b == 0) ? 0xFFFFFFFF : 0
6848*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6849*35ffd701SAndroid Build Coastguard Worker int32x4_t zeroMask = vreinterpretq_s32_u32(vceqzq_s32(b));
6850*35ffd701SAndroid Build Coastguard Worker #else
6851*35ffd701SAndroid Build Coastguard Worker int32x4_t zeroMask = vreinterpretq_s32_u32(vceqq_s32(b, vdupq_n_s32(0)));
6852*35ffd701SAndroid Build Coastguard Worker #endif
6853*35ffd701SAndroid Build Coastguard Worker
6854*35ffd701SAndroid Build Coastguard Worker // bitwise select either a or negative 'a' (vnegq_s32(a) equals to negative
6855*35ffd701SAndroid Build Coastguard Worker // 'a') based on ltMask
6856*35ffd701SAndroid Build Coastguard Worker int32x4_t masked = vbslq_s32(ltMask, vnegq_s32(a), a);
6857*35ffd701SAndroid Build Coastguard Worker // res = masked & (~zeroMask)
6858*35ffd701SAndroid Build Coastguard Worker int32x4_t res = vbicq_s32(masked, zeroMask);
6859*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(res);
6860*35ffd701SAndroid Build Coastguard Worker }
6861*35ffd701SAndroid Build Coastguard Worker
6862*35ffd701SAndroid Build Coastguard Worker // Negate packed 8-bit integers in a when the corresponding signed
6863*35ffd701SAndroid Build Coastguard Worker // 8-bit integer in b is negative, and store the results in dst.
6864*35ffd701SAndroid Build Coastguard Worker // Element in dst are zeroed out when the corresponding element
6865*35ffd701SAndroid Build Coastguard Worker // in b is zero.
6866*35ffd701SAndroid Build Coastguard Worker //
6867*35ffd701SAndroid Build Coastguard Worker // for i in 0..15
6868*35ffd701SAndroid Build Coastguard Worker // if b[i] < 0
6869*35ffd701SAndroid Build Coastguard Worker // r[i] := -a[i]
6870*35ffd701SAndroid Build Coastguard Worker // else if b[i] == 0
6871*35ffd701SAndroid Build Coastguard Worker // r[i] := 0
6872*35ffd701SAndroid Build Coastguard Worker // else
6873*35ffd701SAndroid Build Coastguard Worker // r[i] := a[i]
6874*35ffd701SAndroid Build Coastguard Worker // fi
6875*35ffd701SAndroid Build Coastguard Worker // done
_mm_sign_epi8(__m128i _a,__m128i _b)6876*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_sign_epi8(__m128i _a, __m128i _b)
6877*35ffd701SAndroid Build Coastguard Worker {
6878*35ffd701SAndroid Build Coastguard Worker int8x16_t a = vreinterpretq_s8_m128i(_a);
6879*35ffd701SAndroid Build Coastguard Worker int8x16_t b = vreinterpretq_s8_m128i(_b);
6880*35ffd701SAndroid Build Coastguard Worker
6881*35ffd701SAndroid Build Coastguard Worker // signed shift right: faster than vclt
6882*35ffd701SAndroid Build Coastguard Worker // (b < 0) ? 0xFF : 0
6883*35ffd701SAndroid Build Coastguard Worker uint8x16_t ltMask = vreinterpretq_u8_s8(vshrq_n_s8(b, 7));
6884*35ffd701SAndroid Build Coastguard Worker
6885*35ffd701SAndroid Build Coastguard Worker // (b == 0) ? 0xFF : 0
6886*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6887*35ffd701SAndroid Build Coastguard Worker int8x16_t zeroMask = vreinterpretq_s8_u8(vceqzq_s8(b));
6888*35ffd701SAndroid Build Coastguard Worker #else
6889*35ffd701SAndroid Build Coastguard Worker int8x16_t zeroMask = vreinterpretq_s8_u8(vceqq_s8(b, vdupq_n_s8(0)));
6890*35ffd701SAndroid Build Coastguard Worker #endif
6891*35ffd701SAndroid Build Coastguard Worker
6892*35ffd701SAndroid Build Coastguard Worker // bitwise select either a or nagative 'a' (vnegq_s8(a) return nagative 'a')
6893*35ffd701SAndroid Build Coastguard Worker // based on ltMask
6894*35ffd701SAndroid Build Coastguard Worker int8x16_t masked = vbslq_s8(ltMask, vnegq_s8(a), a);
6895*35ffd701SAndroid Build Coastguard Worker // res = masked & (~zeroMask)
6896*35ffd701SAndroid Build Coastguard Worker int8x16_t res = vbicq_s8(masked, zeroMask);
6897*35ffd701SAndroid Build Coastguard Worker
6898*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(res);
6899*35ffd701SAndroid Build Coastguard Worker }
6900*35ffd701SAndroid Build Coastguard Worker
6901*35ffd701SAndroid Build Coastguard Worker // Negate packed 16-bit integers in a when the corresponding signed 16-bit
6902*35ffd701SAndroid Build Coastguard Worker // integer in b is negative, and store the results in dst. Element in dst are
6903*35ffd701SAndroid Build Coastguard Worker // zeroed out when the corresponding element in b is zero.
6904*35ffd701SAndroid Build Coastguard Worker //
6905*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 3
6906*35ffd701SAndroid Build Coastguard Worker // i := j*16
6907*35ffd701SAndroid Build Coastguard Worker // IF b[i+15:i] < 0
6908*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := -(a[i+15:i])
6909*35ffd701SAndroid Build Coastguard Worker // ELSE IF b[i+15:i] == 0
6910*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := 0
6911*35ffd701SAndroid Build Coastguard Worker // ELSE
6912*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := a[i+15:i]
6913*35ffd701SAndroid Build Coastguard Worker // FI
6914*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6915*35ffd701SAndroid Build Coastguard Worker //
6916*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi16
_mm_sign_pi16(__m64 _a,__m64 _b)6917*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_sign_pi16(__m64 _a, __m64 _b)
6918*35ffd701SAndroid Build Coastguard Worker {
6919*35ffd701SAndroid Build Coastguard Worker int16x4_t a = vreinterpret_s16_m64(_a);
6920*35ffd701SAndroid Build Coastguard Worker int16x4_t b = vreinterpret_s16_m64(_b);
6921*35ffd701SAndroid Build Coastguard Worker
6922*35ffd701SAndroid Build Coastguard Worker // signed shift right: faster than vclt
6923*35ffd701SAndroid Build Coastguard Worker // (b < 0) ? 0xFFFF : 0
6924*35ffd701SAndroid Build Coastguard Worker uint16x4_t ltMask = vreinterpret_u16_s16(vshr_n_s16(b, 15));
6925*35ffd701SAndroid Build Coastguard Worker
6926*35ffd701SAndroid Build Coastguard Worker // (b == 0) ? 0xFFFF : 0
6927*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6928*35ffd701SAndroid Build Coastguard Worker int16x4_t zeroMask = vreinterpret_s16_u16(vceqz_s16(b));
6929*35ffd701SAndroid Build Coastguard Worker #else
6930*35ffd701SAndroid Build Coastguard Worker int16x4_t zeroMask = vreinterpret_s16_u16(vceq_s16(b, vdup_n_s16(0)));
6931*35ffd701SAndroid Build Coastguard Worker #endif
6932*35ffd701SAndroid Build Coastguard Worker
6933*35ffd701SAndroid Build Coastguard Worker // bitwise select either a or nagative 'a' (vneg_s16(a) return nagative 'a')
6934*35ffd701SAndroid Build Coastguard Worker // based on ltMask
6935*35ffd701SAndroid Build Coastguard Worker int16x4_t masked = vbsl_s16(ltMask, vneg_s16(a), a);
6936*35ffd701SAndroid Build Coastguard Worker // res = masked & (~zeroMask)
6937*35ffd701SAndroid Build Coastguard Worker int16x4_t res = vbic_s16(masked, zeroMask);
6938*35ffd701SAndroid Build Coastguard Worker
6939*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s16(res);
6940*35ffd701SAndroid Build Coastguard Worker }
6941*35ffd701SAndroid Build Coastguard Worker
6942*35ffd701SAndroid Build Coastguard Worker // Negate packed 32-bit integers in a when the corresponding signed 32-bit
6943*35ffd701SAndroid Build Coastguard Worker // integer in b is negative, and store the results in dst. Element in dst are
6944*35ffd701SAndroid Build Coastguard Worker // zeroed out when the corresponding element in b is zero.
6945*35ffd701SAndroid Build Coastguard Worker //
6946*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 1
6947*35ffd701SAndroid Build Coastguard Worker // i := j*32
6948*35ffd701SAndroid Build Coastguard Worker // IF b[i+31:i] < 0
6949*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := -(a[i+31:i])
6950*35ffd701SAndroid Build Coastguard Worker // ELSE IF b[i+31:i] == 0
6951*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := 0
6952*35ffd701SAndroid Build Coastguard Worker // ELSE
6953*35ffd701SAndroid Build Coastguard Worker // dst[i+31:i] := a[i+31:i]
6954*35ffd701SAndroid Build Coastguard Worker // FI
6955*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6956*35ffd701SAndroid Build Coastguard Worker //
6957*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi32
_mm_sign_pi32(__m64 _a,__m64 _b)6958*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_sign_pi32(__m64 _a, __m64 _b)
6959*35ffd701SAndroid Build Coastguard Worker {
6960*35ffd701SAndroid Build Coastguard Worker int32x2_t a = vreinterpret_s32_m64(_a);
6961*35ffd701SAndroid Build Coastguard Worker int32x2_t b = vreinterpret_s32_m64(_b);
6962*35ffd701SAndroid Build Coastguard Worker
6963*35ffd701SAndroid Build Coastguard Worker // signed shift right: faster than vclt
6964*35ffd701SAndroid Build Coastguard Worker // (b < 0) ? 0xFFFFFFFF : 0
6965*35ffd701SAndroid Build Coastguard Worker uint32x2_t ltMask = vreinterpret_u32_s32(vshr_n_s32(b, 31));
6966*35ffd701SAndroid Build Coastguard Worker
6967*35ffd701SAndroid Build Coastguard Worker // (b == 0) ? 0xFFFFFFFF : 0
6968*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
6969*35ffd701SAndroid Build Coastguard Worker int32x2_t zeroMask = vreinterpret_s32_u32(vceqz_s32(b));
6970*35ffd701SAndroid Build Coastguard Worker #else
6971*35ffd701SAndroid Build Coastguard Worker int32x2_t zeroMask = vreinterpret_s32_u32(vceq_s32(b, vdup_n_s32(0)));
6972*35ffd701SAndroid Build Coastguard Worker #endif
6973*35ffd701SAndroid Build Coastguard Worker
6974*35ffd701SAndroid Build Coastguard Worker // bitwise select either a or nagative 'a' (vneg_s32(a) return nagative 'a')
6975*35ffd701SAndroid Build Coastguard Worker // based on ltMask
6976*35ffd701SAndroid Build Coastguard Worker int32x2_t masked = vbsl_s32(ltMask, vneg_s32(a), a);
6977*35ffd701SAndroid Build Coastguard Worker // res = masked & (~zeroMask)
6978*35ffd701SAndroid Build Coastguard Worker int32x2_t res = vbic_s32(masked, zeroMask);
6979*35ffd701SAndroid Build Coastguard Worker
6980*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s32(res);
6981*35ffd701SAndroid Build Coastguard Worker }
6982*35ffd701SAndroid Build Coastguard Worker
6983*35ffd701SAndroid Build Coastguard Worker // Negate packed 8-bit integers in a when the corresponding signed 8-bit integer
6984*35ffd701SAndroid Build Coastguard Worker // in b is negative, and store the results in dst. Element in dst are zeroed out
6985*35ffd701SAndroid Build Coastguard Worker // when the corresponding element in b is zero.
6986*35ffd701SAndroid Build Coastguard Worker //
6987*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
6988*35ffd701SAndroid Build Coastguard Worker // i := j*8
6989*35ffd701SAndroid Build Coastguard Worker // IF b[i+7:i] < 0
6990*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := -(a[i+7:i])
6991*35ffd701SAndroid Build Coastguard Worker // ELSE IF b[i+7:i] == 0
6992*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := 0
6993*35ffd701SAndroid Build Coastguard Worker // ELSE
6994*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := a[i+7:i]
6995*35ffd701SAndroid Build Coastguard Worker // FI
6996*35ffd701SAndroid Build Coastguard Worker // ENDFOR
6997*35ffd701SAndroid Build Coastguard Worker //
6998*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sign_pi8
_mm_sign_pi8(__m64 _a,__m64 _b)6999*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m64 _mm_sign_pi8(__m64 _a, __m64 _b)
7000*35ffd701SAndroid Build Coastguard Worker {
7001*35ffd701SAndroid Build Coastguard Worker int8x8_t a = vreinterpret_s8_m64(_a);
7002*35ffd701SAndroid Build Coastguard Worker int8x8_t b = vreinterpret_s8_m64(_b);
7003*35ffd701SAndroid Build Coastguard Worker
7004*35ffd701SAndroid Build Coastguard Worker // signed shift right: faster than vclt
7005*35ffd701SAndroid Build Coastguard Worker // (b < 0) ? 0xFF : 0
7006*35ffd701SAndroid Build Coastguard Worker uint8x8_t ltMask = vreinterpret_u8_s8(vshr_n_s8(b, 7));
7007*35ffd701SAndroid Build Coastguard Worker
7008*35ffd701SAndroid Build Coastguard Worker // (b == 0) ? 0xFF : 0
7009*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7010*35ffd701SAndroid Build Coastguard Worker int8x8_t zeroMask = vreinterpret_s8_u8(vceqz_s8(b));
7011*35ffd701SAndroid Build Coastguard Worker #else
7012*35ffd701SAndroid Build Coastguard Worker int8x8_t zeroMask = vreinterpret_s8_u8(vceq_s8(b, vdup_n_s8(0)));
7013*35ffd701SAndroid Build Coastguard Worker #endif
7014*35ffd701SAndroid Build Coastguard Worker
7015*35ffd701SAndroid Build Coastguard Worker // bitwise select either a or nagative 'a' (vneg_s8(a) return nagative 'a')
7016*35ffd701SAndroid Build Coastguard Worker // based on ltMask
7017*35ffd701SAndroid Build Coastguard Worker int8x8_t masked = vbsl_s8(ltMask, vneg_s8(a), a);
7018*35ffd701SAndroid Build Coastguard Worker // res = masked & (~zeroMask)
7019*35ffd701SAndroid Build Coastguard Worker int8x8_t res = vbic_s8(masked, zeroMask);
7020*35ffd701SAndroid Build Coastguard Worker
7021*35ffd701SAndroid Build Coastguard Worker return vreinterpret_m64_s8(res);
7022*35ffd701SAndroid Build Coastguard Worker }
7023*35ffd701SAndroid Build Coastguard Worker
7024*35ffd701SAndroid Build Coastguard Worker /* SSE4.1 */
7025*35ffd701SAndroid Build Coastguard Worker
7026*35ffd701SAndroid Build Coastguard Worker // Blend packed 16-bit integers from a and b using control mask imm8, and store
7027*35ffd701SAndroid Build Coastguard Worker // the results in dst.
7028*35ffd701SAndroid Build Coastguard Worker //
7029*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
7030*35ffd701SAndroid Build Coastguard Worker // i := j*16
7031*35ffd701SAndroid Build Coastguard Worker // IF imm8[j]
7032*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := b[i+15:i]
7033*35ffd701SAndroid Build Coastguard Worker // ELSE
7034*35ffd701SAndroid Build Coastguard Worker // dst[i+15:i] := a[i+15:i]
7035*35ffd701SAndroid Build Coastguard Worker // FI
7036*35ffd701SAndroid Build Coastguard Worker // ENDFOR
7037*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_blend_epi16(__m128i a, __m128i b,
7038*35ffd701SAndroid Build Coastguard Worker // __constrange(0,255) int imm)
7039*35ffd701SAndroid Build Coastguard Worker #define _mm_blend_epi16(a, b, imm) \
7040*35ffd701SAndroid Build Coastguard Worker __extension__({ \
7041*35ffd701SAndroid Build Coastguard Worker const uint16_t _mask[8] = {((imm) & (1 << 0)) ? (uint16_t) -1 : 0x0, \
7042*35ffd701SAndroid Build Coastguard Worker ((imm) & (1 << 1)) ? (uint16_t) -1 : 0x0, \
7043*35ffd701SAndroid Build Coastguard Worker ((imm) & (1 << 2)) ? (uint16_t) -1 : 0x0, \
7044*35ffd701SAndroid Build Coastguard Worker ((imm) & (1 << 3)) ? (uint16_t) -1 : 0x0, \
7045*35ffd701SAndroid Build Coastguard Worker ((imm) & (1 << 4)) ? (uint16_t) -1 : 0x0, \
7046*35ffd701SAndroid Build Coastguard Worker ((imm) & (1 << 5)) ? (uint16_t) -1 : 0x0, \
7047*35ffd701SAndroid Build Coastguard Worker ((imm) & (1 << 6)) ? (uint16_t) -1 : 0x0, \
7048*35ffd701SAndroid Build Coastguard Worker ((imm) & (1 << 7)) ? (uint16_t) -1 : 0x0}; \
7049*35ffd701SAndroid Build Coastguard Worker uint16x8_t _mask_vec = vld1q_u16(_mask); \
7050*35ffd701SAndroid Build Coastguard Worker uint16x8_t _a = vreinterpretq_u16_m128i(a); \
7051*35ffd701SAndroid Build Coastguard Worker uint16x8_t _b = vreinterpretq_u16_m128i(b); \
7052*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \
7053*35ffd701SAndroid Build Coastguard Worker })
7054*35ffd701SAndroid Build Coastguard Worker
7055*35ffd701SAndroid Build Coastguard Worker // Blend packed double-precision (64-bit) floating-point elements from a and b
7056*35ffd701SAndroid Build Coastguard Worker // using control mask imm8, and store the results in dst.
7057*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_pd
7058*35ffd701SAndroid Build Coastguard Worker #define _mm_blend_pd(a, b, imm) \
7059*35ffd701SAndroid Build Coastguard Worker __extension__({ \
7060*35ffd701SAndroid Build Coastguard Worker const uint64_t _mask[2] = { \
7061*35ffd701SAndroid Build Coastguard Worker ((imm) & (1 << 0)) ? ~UINT64_C(0) : UINT64_C(0), \
7062*35ffd701SAndroid Build Coastguard Worker ((imm) & (1 << 1)) ? ~UINT64_C(0) : UINT64_C(0)}; \
7063*35ffd701SAndroid Build Coastguard Worker uint64x2_t _mask_vec = vld1q_u64(_mask); \
7064*35ffd701SAndroid Build Coastguard Worker uint64x2_t _a = vreinterpretq_u64_m128d(a); \
7065*35ffd701SAndroid Build Coastguard Worker uint64x2_t _b = vreinterpretq_u64_m128d(b); \
7066*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128d_u64(vbslq_u64(_mask_vec, _b, _a)); \
7067*35ffd701SAndroid Build Coastguard Worker })
7068*35ffd701SAndroid Build Coastguard Worker
7069*35ffd701SAndroid Build Coastguard Worker // Blend packed single-precision (32-bit) floating-point elements from a and b
7070*35ffd701SAndroid Build Coastguard Worker // using mask, and store the results in dst.
7071*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_ps
_mm_blend_ps(__m128 _a,__m128 _b,const char imm8)7072*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_blend_ps(__m128 _a, __m128 _b, const char imm8)
7073*35ffd701SAndroid Build Coastguard Worker {
7074*35ffd701SAndroid Build Coastguard Worker const uint32_t ALIGN_STRUCT(16)
7075*35ffd701SAndroid Build Coastguard Worker data[4] = {((imm8) & (1 << 0)) ? UINT32_MAX : 0,
7076*35ffd701SAndroid Build Coastguard Worker ((imm8) & (1 << 1)) ? UINT32_MAX : 0,
7077*35ffd701SAndroid Build Coastguard Worker ((imm8) & (1 << 2)) ? UINT32_MAX : 0,
7078*35ffd701SAndroid Build Coastguard Worker ((imm8) & (1 << 3)) ? UINT32_MAX : 0};
7079*35ffd701SAndroid Build Coastguard Worker uint32x4_t mask = vld1q_u32(data);
7080*35ffd701SAndroid Build Coastguard Worker float32x4_t a = vreinterpretq_f32_m128(_a);
7081*35ffd701SAndroid Build Coastguard Worker float32x4_t b = vreinterpretq_f32_m128(_b);
7082*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vbslq_f32(mask, b, a));
7083*35ffd701SAndroid Build Coastguard Worker }
7084*35ffd701SAndroid Build Coastguard Worker
7085*35ffd701SAndroid Build Coastguard Worker // Blend packed 8-bit integers from a and b using mask, and store the results in
7086*35ffd701SAndroid Build Coastguard Worker // dst.
7087*35ffd701SAndroid Build Coastguard Worker //
7088*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 15
7089*35ffd701SAndroid Build Coastguard Worker // i := j*8
7090*35ffd701SAndroid Build Coastguard Worker // IF mask[i+7]
7091*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := b[i+7:i]
7092*35ffd701SAndroid Build Coastguard Worker // ELSE
7093*35ffd701SAndroid Build Coastguard Worker // dst[i+7:i] := a[i+7:i]
7094*35ffd701SAndroid Build Coastguard Worker // FI
7095*35ffd701SAndroid Build Coastguard Worker // ENDFOR
_mm_blendv_epi8(__m128i _a,__m128i _b,__m128i _mask)7096*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_blendv_epi8(__m128i _a, __m128i _b, __m128i _mask)
7097*35ffd701SAndroid Build Coastguard Worker {
7098*35ffd701SAndroid Build Coastguard Worker // Use a signed shift right to create a mask with the sign bit
7099*35ffd701SAndroid Build Coastguard Worker uint8x16_t mask =
7100*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_s8(vshrq_n_s8(vreinterpretq_s8_m128i(_mask), 7));
7101*35ffd701SAndroid Build Coastguard Worker uint8x16_t a = vreinterpretq_u8_m128i(_a);
7102*35ffd701SAndroid Build Coastguard Worker uint8x16_t b = vreinterpretq_u8_m128i(_b);
7103*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(vbslq_u8(mask, b, a));
7104*35ffd701SAndroid Build Coastguard Worker }
7105*35ffd701SAndroid Build Coastguard Worker
7106*35ffd701SAndroid Build Coastguard Worker // Blend packed double-precision (64-bit) floating-point elements from a and b
7107*35ffd701SAndroid Build Coastguard Worker // using mask, and store the results in dst.
7108*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_pd
_mm_blendv_pd(__m128d _a,__m128d _b,__m128d _mask)7109*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_blendv_pd(__m128d _a, __m128d _b, __m128d _mask)
7110*35ffd701SAndroid Build Coastguard Worker {
7111*35ffd701SAndroid Build Coastguard Worker uint64x2_t mask =
7112*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u64_s64(vshrq_n_s64(vreinterpretq_s64_m128d(_mask), 63));
7113*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7114*35ffd701SAndroid Build Coastguard Worker float64x2_t a = vreinterpretq_f64_m128d(_a);
7115*35ffd701SAndroid Build Coastguard Worker float64x2_t b = vreinterpretq_f64_m128d(_b);
7116*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vbslq_f64(mask, b, a));
7117*35ffd701SAndroid Build Coastguard Worker #else
7118*35ffd701SAndroid Build Coastguard Worker uint64x2_t a = vreinterpretq_u64_m128d(_a);
7119*35ffd701SAndroid Build Coastguard Worker uint64x2_t b = vreinterpretq_u64_m128d(_b);
7120*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_u64(vbslq_u64(mask, b, a));
7121*35ffd701SAndroid Build Coastguard Worker #endif
7122*35ffd701SAndroid Build Coastguard Worker }
7123*35ffd701SAndroid Build Coastguard Worker
7124*35ffd701SAndroid Build Coastguard Worker // Blend packed single-precision (32-bit) floating-point elements from a and b
7125*35ffd701SAndroid Build Coastguard Worker // using mask, and store the results in dst.
7126*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_ps
_mm_blendv_ps(__m128 _a,__m128 _b,__m128 _mask)7127*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_blendv_ps(__m128 _a, __m128 _b, __m128 _mask)
7128*35ffd701SAndroid Build Coastguard Worker {
7129*35ffd701SAndroid Build Coastguard Worker // Use a signed shift right to create a mask with the sign bit
7130*35ffd701SAndroid Build Coastguard Worker uint32x4_t mask =
7131*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u32_s32(vshrq_n_s32(vreinterpretq_s32_m128(_mask), 31));
7132*35ffd701SAndroid Build Coastguard Worker float32x4_t a = vreinterpretq_f32_m128(_a);
7133*35ffd701SAndroid Build Coastguard Worker float32x4_t b = vreinterpretq_f32_m128(_b);
7134*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vbslq_f32(mask, b, a));
7135*35ffd701SAndroid Build Coastguard Worker }
7136*35ffd701SAndroid Build Coastguard Worker
7137*35ffd701SAndroid Build Coastguard Worker // Round the packed double-precision (64-bit) floating-point elements in a up
7138*35ffd701SAndroid Build Coastguard Worker // to an integer value, and store the results as packed double-precision
7139*35ffd701SAndroid Build Coastguard Worker // floating-point elements in dst.
7140*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_pd
_mm_ceil_pd(__m128d a)7141*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_ceil_pd(__m128d a)
7142*35ffd701SAndroid Build Coastguard Worker {
7143*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7144*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vrndpq_f64(vreinterpretq_f64_m128d(a)));
7145*35ffd701SAndroid Build Coastguard Worker #else
7146*35ffd701SAndroid Build Coastguard Worker double *f = (double *) &a;
7147*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(ceil(f[1]), ceil(f[0]));
7148*35ffd701SAndroid Build Coastguard Worker #endif
7149*35ffd701SAndroid Build Coastguard Worker }
7150*35ffd701SAndroid Build Coastguard Worker
7151*35ffd701SAndroid Build Coastguard Worker // Round the packed single-precision (32-bit) floating-point elements in a up to
7152*35ffd701SAndroid Build Coastguard Worker // an integer value, and store the results as packed single-precision
7153*35ffd701SAndroid Build Coastguard Worker // floating-point elements in dst.
7154*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ps
_mm_ceil_ps(__m128 a)7155*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_ceil_ps(__m128 a)
7156*35ffd701SAndroid Build Coastguard Worker {
7157*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7158*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vrndpq_f32(vreinterpretq_f32_m128(a)));
7159*35ffd701SAndroid Build Coastguard Worker #else
7160*35ffd701SAndroid Build Coastguard Worker float *f = (float *) &a;
7161*35ffd701SAndroid Build Coastguard Worker return _mm_set_ps(ceilf(f[3]), ceilf(f[2]), ceilf(f[1]), ceilf(f[0]));
7162*35ffd701SAndroid Build Coastguard Worker #endif
7163*35ffd701SAndroid Build Coastguard Worker }
7164*35ffd701SAndroid Build Coastguard Worker
7165*35ffd701SAndroid Build Coastguard Worker // Round the lower double-precision (64-bit) floating-point element in b up to
7166*35ffd701SAndroid Build Coastguard Worker // an integer value, store the result as a double-precision floating-point
7167*35ffd701SAndroid Build Coastguard Worker // element in the lower element of dst, and copy the upper element from a to the
7168*35ffd701SAndroid Build Coastguard Worker // upper element of dst.
7169*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_sd
_mm_ceil_sd(__m128d a,__m128d b)7170*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_ceil_sd(__m128d a, __m128d b)
7171*35ffd701SAndroid Build Coastguard Worker {
7172*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_ceil_pd(b));
7173*35ffd701SAndroid Build Coastguard Worker }
7174*35ffd701SAndroid Build Coastguard Worker
7175*35ffd701SAndroid Build Coastguard Worker // Round the lower single-precision (32-bit) floating-point element in b up to
7176*35ffd701SAndroid Build Coastguard Worker // an integer value, store the result as a single-precision floating-point
7177*35ffd701SAndroid Build Coastguard Worker // element in the lower element of dst, and copy the upper 3 packed elements
7178*35ffd701SAndroid Build Coastguard Worker // from a to the upper elements of dst.
7179*35ffd701SAndroid Build Coastguard Worker //
7180*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := CEIL(b[31:0])
7181*35ffd701SAndroid Build Coastguard Worker // dst[127:32] := a[127:32]
7182*35ffd701SAndroid Build Coastguard Worker //
7183*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ss
_mm_ceil_ss(__m128 a,__m128 b)7184*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_ceil_ss(__m128 a, __m128 b)
7185*35ffd701SAndroid Build Coastguard Worker {
7186*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_ceil_ps(b));
7187*35ffd701SAndroid Build Coastguard Worker }
7188*35ffd701SAndroid Build Coastguard Worker
7189*35ffd701SAndroid Build Coastguard Worker // Compare packed 64-bit integers in a and b for equality, and store the results
7190*35ffd701SAndroid Build Coastguard Worker // in dst
_mm_cmpeq_epi64(__m128i a,__m128i b)7191*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmpeq_epi64(__m128i a, __m128i b)
7192*35ffd701SAndroid Build Coastguard Worker {
7193*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7194*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(
7195*35ffd701SAndroid Build Coastguard Worker vceqq_u64(vreinterpretq_u64_m128i(a), vreinterpretq_u64_m128i(b)));
7196*35ffd701SAndroid Build Coastguard Worker #else
7197*35ffd701SAndroid Build Coastguard Worker // ARMv7 lacks vceqq_u64
7198*35ffd701SAndroid Build Coastguard Worker // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi)
7199*35ffd701SAndroid Build Coastguard Worker uint32x4_t cmp =
7200*35ffd701SAndroid Build Coastguard Worker vceqq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b));
7201*35ffd701SAndroid Build Coastguard Worker uint32x4_t swapped = vrev64q_u32(cmp);
7202*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u32(vandq_u32(cmp, swapped));
7203*35ffd701SAndroid Build Coastguard Worker #endif
7204*35ffd701SAndroid Build Coastguard Worker }
7205*35ffd701SAndroid Build Coastguard Worker
7206*35ffd701SAndroid Build Coastguard Worker // Converts the four signed 16-bit integers in the lower 64 bits to four signed
7207*35ffd701SAndroid Build Coastguard Worker // 32-bit integers.
_mm_cvtepi16_epi32(__m128i a)7208*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepi16_epi32(__m128i a)
7209*35ffd701SAndroid Build Coastguard Worker {
7210*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
7211*35ffd701SAndroid Build Coastguard Worker vmovl_s16(vget_low_s16(vreinterpretq_s16_m128i(a))));
7212*35ffd701SAndroid Build Coastguard Worker }
7213*35ffd701SAndroid Build Coastguard Worker
7214*35ffd701SAndroid Build Coastguard Worker // Converts the two signed 16-bit integers in the lower 32 bits two signed
7215*35ffd701SAndroid Build Coastguard Worker // 32-bit integers.
_mm_cvtepi16_epi64(__m128i a)7216*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepi16_epi64(__m128i a)
7217*35ffd701SAndroid Build Coastguard Worker {
7218*35ffd701SAndroid Build Coastguard Worker int16x8_t s16x8 = vreinterpretq_s16_m128i(a); /* xxxx xxxx xxxx 0B0A */
7219*35ffd701SAndroid Build Coastguard Worker int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */
7220*35ffd701SAndroid Build Coastguard Worker int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */
7221*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(s64x2);
7222*35ffd701SAndroid Build Coastguard Worker }
7223*35ffd701SAndroid Build Coastguard Worker
7224*35ffd701SAndroid Build Coastguard Worker // Converts the two signed 32-bit integers in the lower 64 bits to two signed
7225*35ffd701SAndroid Build Coastguard Worker // 64-bit integers.
_mm_cvtepi32_epi64(__m128i a)7226*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepi32_epi64(__m128i a)
7227*35ffd701SAndroid Build Coastguard Worker {
7228*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(
7229*35ffd701SAndroid Build Coastguard Worker vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a))));
7230*35ffd701SAndroid Build Coastguard Worker }
7231*35ffd701SAndroid Build Coastguard Worker
7232*35ffd701SAndroid Build Coastguard Worker // Converts the four unsigned 8-bit integers in the lower 16 bits to four
7233*35ffd701SAndroid Build Coastguard Worker // unsigned 32-bit integers.
_mm_cvtepi8_epi16(__m128i a)7234*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepi8_epi16(__m128i a)
7235*35ffd701SAndroid Build Coastguard Worker {
7236*35ffd701SAndroid Build Coastguard Worker int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */
7237*35ffd701SAndroid Build Coastguard Worker int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */
7238*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s16(s16x8);
7239*35ffd701SAndroid Build Coastguard Worker }
7240*35ffd701SAndroid Build Coastguard Worker
7241*35ffd701SAndroid Build Coastguard Worker // Converts the four unsigned 8-bit integers in the lower 32 bits to four
7242*35ffd701SAndroid Build Coastguard Worker // unsigned 32-bit integers.
_mm_cvtepi8_epi32(__m128i a)7243*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepi8_epi32(__m128i a)
7244*35ffd701SAndroid Build Coastguard Worker {
7245*35ffd701SAndroid Build Coastguard Worker int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */
7246*35ffd701SAndroid Build Coastguard Worker int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */
7247*35ffd701SAndroid Build Coastguard Worker int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000D 000C 000B 000A */
7248*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(s32x4);
7249*35ffd701SAndroid Build Coastguard Worker }
7250*35ffd701SAndroid Build Coastguard Worker
7251*35ffd701SAndroid Build Coastguard Worker // Converts the two signed 8-bit integers in the lower 32 bits to four
7252*35ffd701SAndroid Build Coastguard Worker // signed 64-bit integers.
_mm_cvtepi8_epi64(__m128i a)7253*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepi8_epi64(__m128i a)
7254*35ffd701SAndroid Build Coastguard Worker {
7255*35ffd701SAndroid Build Coastguard Worker int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx xxBA */
7256*35ffd701SAndroid Build Coastguard Worker int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0x0x 0B0A */
7257*35ffd701SAndroid Build Coastguard Worker int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */
7258*35ffd701SAndroid Build Coastguard Worker int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */
7259*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(s64x2);
7260*35ffd701SAndroid Build Coastguard Worker }
7261*35ffd701SAndroid Build Coastguard Worker
7262*35ffd701SAndroid Build Coastguard Worker // Converts the four unsigned 16-bit integers in the lower 64 bits to four
7263*35ffd701SAndroid Build Coastguard Worker // unsigned 32-bit integers.
_mm_cvtepu16_epi32(__m128i a)7264*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepu16_epi32(__m128i a)
7265*35ffd701SAndroid Build Coastguard Worker {
7266*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u32(
7267*35ffd701SAndroid Build Coastguard Worker vmovl_u16(vget_low_u16(vreinterpretq_u16_m128i(a))));
7268*35ffd701SAndroid Build Coastguard Worker }
7269*35ffd701SAndroid Build Coastguard Worker
7270*35ffd701SAndroid Build Coastguard Worker // Converts the two unsigned 16-bit integers in the lower 32 bits to two
7271*35ffd701SAndroid Build Coastguard Worker // unsigned 64-bit integers.
_mm_cvtepu16_epi64(__m128i a)7272*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepu16_epi64(__m128i a)
7273*35ffd701SAndroid Build Coastguard Worker {
7274*35ffd701SAndroid Build Coastguard Worker uint16x8_t u16x8 = vreinterpretq_u16_m128i(a); /* xxxx xxxx xxxx 0B0A */
7275*35ffd701SAndroid Build Coastguard Worker uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */
7276*35ffd701SAndroid Build Coastguard Worker uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */
7277*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(u64x2);
7278*35ffd701SAndroid Build Coastguard Worker }
7279*35ffd701SAndroid Build Coastguard Worker
7280*35ffd701SAndroid Build Coastguard Worker // Converts the two unsigned 32-bit integers in the lower 64 bits to two
7281*35ffd701SAndroid Build Coastguard Worker // unsigned 64-bit integers.
_mm_cvtepu32_epi64(__m128i a)7282*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepu32_epi64(__m128i a)
7283*35ffd701SAndroid Build Coastguard Worker {
7284*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(
7285*35ffd701SAndroid Build Coastguard Worker vmovl_u32(vget_low_u32(vreinterpretq_u32_m128i(a))));
7286*35ffd701SAndroid Build Coastguard Worker }
7287*35ffd701SAndroid Build Coastguard Worker
7288*35ffd701SAndroid Build Coastguard Worker // Zero extend packed unsigned 8-bit integers in a to packed 16-bit integers,
7289*35ffd701SAndroid Build Coastguard Worker // and store the results in dst.
7290*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtepu8_epi16
_mm_cvtepu8_epi16(__m128i a)7291*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepu8_epi16(__m128i a)
7292*35ffd701SAndroid Build Coastguard Worker {
7293*35ffd701SAndroid Build Coastguard Worker uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx HGFE DCBA */
7294*35ffd701SAndroid Build Coastguard Worker uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0H0G 0F0E 0D0C 0B0A */
7295*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(u16x8);
7296*35ffd701SAndroid Build Coastguard Worker }
7297*35ffd701SAndroid Build Coastguard Worker
7298*35ffd701SAndroid Build Coastguard Worker // Converts the four unsigned 8-bit integers in the lower 32 bits to four
7299*35ffd701SAndroid Build Coastguard Worker // unsigned 32-bit integers.
7300*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/bb531467%28v=vs.100%29.aspx
_mm_cvtepu8_epi32(__m128i a)7301*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepu8_epi32(__m128i a)
7302*35ffd701SAndroid Build Coastguard Worker {
7303*35ffd701SAndroid Build Coastguard Worker uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */
7304*35ffd701SAndroid Build Coastguard Worker uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */
7305*35ffd701SAndroid Build Coastguard Worker uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000D 000C 000B 000A */
7306*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u32(u32x4);
7307*35ffd701SAndroid Build Coastguard Worker }
7308*35ffd701SAndroid Build Coastguard Worker
7309*35ffd701SAndroid Build Coastguard Worker // Converts the two unsigned 8-bit integers in the lower 16 bits to two
7310*35ffd701SAndroid Build Coastguard Worker // unsigned 64-bit integers.
_mm_cvtepu8_epi64(__m128i a)7311*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cvtepu8_epi64(__m128i a)
7312*35ffd701SAndroid Build Coastguard Worker {
7313*35ffd701SAndroid Build Coastguard Worker uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx xxBA */
7314*35ffd701SAndroid Build Coastguard Worker uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0x0x 0B0A */
7315*35ffd701SAndroid Build Coastguard Worker uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */
7316*35ffd701SAndroid Build Coastguard Worker uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */
7317*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(u64x2);
7318*35ffd701SAndroid Build Coastguard Worker }
7319*35ffd701SAndroid Build Coastguard Worker
7320*35ffd701SAndroid Build Coastguard Worker // Conditionally multiply the packed single-precision (32-bit) floating-point
7321*35ffd701SAndroid Build Coastguard Worker // elements in a and b using the high 4 bits in imm8, sum the four products,
7322*35ffd701SAndroid Build Coastguard Worker // and conditionally store the sum in dst using the low 4 bits of imm.
7323*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_dp_ps
_mm_dp_ps(__m128 a,__m128 b,const int imm)7324*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_dp_ps(__m128 a, __m128 b, const int imm)
7325*35ffd701SAndroid Build Coastguard Worker {
7326*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7327*35ffd701SAndroid Build Coastguard Worker /* shortcuts */
7328*35ffd701SAndroid Build Coastguard Worker if (imm == 0xFF) {
7329*35ffd701SAndroid Build Coastguard Worker return _mm_set1_ps(vaddvq_f32(_mm_mul_ps(a, b)));
7330*35ffd701SAndroid Build Coastguard Worker }
7331*35ffd701SAndroid Build Coastguard Worker if (imm == 0x7F) {
7332*35ffd701SAndroid Build Coastguard Worker float32x4_t m = _mm_mul_ps(a, b);
7333*35ffd701SAndroid Build Coastguard Worker m[3] = 0;
7334*35ffd701SAndroid Build Coastguard Worker return _mm_set1_ps(vaddvq_f32(m));
7335*35ffd701SAndroid Build Coastguard Worker }
7336*35ffd701SAndroid Build Coastguard Worker #endif
7337*35ffd701SAndroid Build Coastguard Worker
7338*35ffd701SAndroid Build Coastguard Worker float s = 0, c = 0;
7339*35ffd701SAndroid Build Coastguard Worker float32x4_t f32a = vreinterpretq_f32_m128(a);
7340*35ffd701SAndroid Build Coastguard Worker float32x4_t f32b = vreinterpretq_f32_m128(b);
7341*35ffd701SAndroid Build Coastguard Worker
7342*35ffd701SAndroid Build Coastguard Worker /* To improve the accuracy of floating-point summation, Kahan algorithm
7343*35ffd701SAndroid Build Coastguard Worker * is used for each operation.
7344*35ffd701SAndroid Build Coastguard Worker */
7345*35ffd701SAndroid Build Coastguard Worker if (imm & (1 << 4))
7346*35ffd701SAndroid Build Coastguard Worker _sse2neon_kadd_f32(&s, &c, f32a[0] * f32b[0]);
7347*35ffd701SAndroid Build Coastguard Worker if (imm & (1 << 5))
7348*35ffd701SAndroid Build Coastguard Worker _sse2neon_kadd_f32(&s, &c, f32a[1] * f32b[1]);
7349*35ffd701SAndroid Build Coastguard Worker if (imm & (1 << 6))
7350*35ffd701SAndroid Build Coastguard Worker _sse2neon_kadd_f32(&s, &c, f32a[2] * f32b[2]);
7351*35ffd701SAndroid Build Coastguard Worker if (imm & (1 << 7))
7352*35ffd701SAndroid Build Coastguard Worker _sse2neon_kadd_f32(&s, &c, f32a[3] * f32b[3]);
7353*35ffd701SAndroid Build Coastguard Worker s += c;
7354*35ffd701SAndroid Build Coastguard Worker
7355*35ffd701SAndroid Build Coastguard Worker float32x4_t res = {
7356*35ffd701SAndroid Build Coastguard Worker (imm & 0x1) ? s : 0,
7357*35ffd701SAndroid Build Coastguard Worker (imm & 0x2) ? s : 0,
7358*35ffd701SAndroid Build Coastguard Worker (imm & 0x4) ? s : 0,
7359*35ffd701SAndroid Build Coastguard Worker (imm & 0x8) ? s : 0,
7360*35ffd701SAndroid Build Coastguard Worker };
7361*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(res);
7362*35ffd701SAndroid Build Coastguard Worker }
7363*35ffd701SAndroid Build Coastguard Worker
7364*35ffd701SAndroid Build Coastguard Worker // Extracts the selected signed or unsigned 32-bit integer from a and zero
7365*35ffd701SAndroid Build Coastguard Worker // extends.
7366*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE int _mm_extract_epi32(__m128i a, __constrange(0,4) int imm)
7367*35ffd701SAndroid Build Coastguard Worker #define _mm_extract_epi32(a, imm) \
7368*35ffd701SAndroid Build Coastguard Worker vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm))
7369*35ffd701SAndroid Build Coastguard Worker
7370*35ffd701SAndroid Build Coastguard Worker // Extracts the selected signed or unsigned 64-bit integer from a and zero
7371*35ffd701SAndroid Build Coastguard Worker // extends.
7372*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __int64 _mm_extract_epi64(__m128i a, __constrange(0,2) int imm)
7373*35ffd701SAndroid Build Coastguard Worker #define _mm_extract_epi64(a, imm) \
7374*35ffd701SAndroid Build Coastguard Worker vgetq_lane_s64(vreinterpretq_s64_m128i(a), (imm))
7375*35ffd701SAndroid Build Coastguard Worker
7376*35ffd701SAndroid Build Coastguard Worker // Extracts the selected signed or unsigned 8-bit integer from a and zero
7377*35ffd701SAndroid Build Coastguard Worker // extends.
7378*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE int _mm_extract_epi8(__m128i a, __constrange(0,16) int imm)
7379*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_extract_epi8
7380*35ffd701SAndroid Build Coastguard Worker #define _mm_extract_epi8(a, imm) vgetq_lane_u8(vreinterpretq_u8_m128i(a), (imm))
7381*35ffd701SAndroid Build Coastguard Worker
7382*35ffd701SAndroid Build Coastguard Worker // Extracts the selected single-precision (32-bit) floating-point from a.
7383*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE int _mm_extract_ps(__m128 a, __constrange(0,4) int imm)
7384*35ffd701SAndroid Build Coastguard Worker #define _mm_extract_ps(a, imm) vgetq_lane_s32(vreinterpretq_s32_m128(a), (imm))
7385*35ffd701SAndroid Build Coastguard Worker
7386*35ffd701SAndroid Build Coastguard Worker // Round the packed double-precision (64-bit) floating-point elements in a down
7387*35ffd701SAndroid Build Coastguard Worker // to an integer value, and store the results as packed double-precision
7388*35ffd701SAndroid Build Coastguard Worker // floating-point elements in dst.
7389*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_pd
_mm_floor_pd(__m128d a)7390*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_floor_pd(__m128d a)
7391*35ffd701SAndroid Build Coastguard Worker {
7392*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7393*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vrndmq_f64(vreinterpretq_f64_m128d(a)));
7394*35ffd701SAndroid Build Coastguard Worker #else
7395*35ffd701SAndroid Build Coastguard Worker double *f = (double *) &a;
7396*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(floor(f[1]), floor(f[0]));
7397*35ffd701SAndroid Build Coastguard Worker #endif
7398*35ffd701SAndroid Build Coastguard Worker }
7399*35ffd701SAndroid Build Coastguard Worker
7400*35ffd701SAndroid Build Coastguard Worker // Round the packed single-precision (32-bit) floating-point elements in a down
7401*35ffd701SAndroid Build Coastguard Worker // to an integer value, and store the results as packed single-precision
7402*35ffd701SAndroid Build Coastguard Worker // floating-point elements in dst.
7403*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ps
_mm_floor_ps(__m128 a)7404*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_floor_ps(__m128 a)
7405*35ffd701SAndroid Build Coastguard Worker {
7406*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7407*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vrndmq_f32(vreinterpretq_f32_m128(a)));
7408*35ffd701SAndroid Build Coastguard Worker #else
7409*35ffd701SAndroid Build Coastguard Worker float *f = (float *) &a;
7410*35ffd701SAndroid Build Coastguard Worker return _mm_set_ps(floorf(f[3]), floorf(f[2]), floorf(f[1]), floorf(f[0]));
7411*35ffd701SAndroid Build Coastguard Worker #endif
7412*35ffd701SAndroid Build Coastguard Worker }
7413*35ffd701SAndroid Build Coastguard Worker
7414*35ffd701SAndroid Build Coastguard Worker // Round the lower double-precision (64-bit) floating-point element in b down to
7415*35ffd701SAndroid Build Coastguard Worker // an integer value, store the result as a double-precision floating-point
7416*35ffd701SAndroid Build Coastguard Worker // element in the lower element of dst, and copy the upper element from a to the
7417*35ffd701SAndroid Build Coastguard Worker // upper element of dst.
7418*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_sd
_mm_floor_sd(__m128d a,__m128d b)7419*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_floor_sd(__m128d a, __m128d b)
7420*35ffd701SAndroid Build Coastguard Worker {
7421*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_floor_pd(b));
7422*35ffd701SAndroid Build Coastguard Worker }
7423*35ffd701SAndroid Build Coastguard Worker
7424*35ffd701SAndroid Build Coastguard Worker // Round the lower single-precision (32-bit) floating-point element in b down to
7425*35ffd701SAndroid Build Coastguard Worker // an integer value, store the result as a single-precision floating-point
7426*35ffd701SAndroid Build Coastguard Worker // element in the lower element of dst, and copy the upper 3 packed elements
7427*35ffd701SAndroid Build Coastguard Worker // from a to the upper elements of dst.
7428*35ffd701SAndroid Build Coastguard Worker //
7429*35ffd701SAndroid Build Coastguard Worker // dst[31:0] := FLOOR(b[31:0])
7430*35ffd701SAndroid Build Coastguard Worker // dst[127:32] := a[127:32]
7431*35ffd701SAndroid Build Coastguard Worker //
7432*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ss
_mm_floor_ss(__m128 a,__m128 b)7433*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_floor_ss(__m128 a, __m128 b)
7434*35ffd701SAndroid Build Coastguard Worker {
7435*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_floor_ps(b));
7436*35ffd701SAndroid Build Coastguard Worker }
7437*35ffd701SAndroid Build Coastguard Worker
7438*35ffd701SAndroid Build Coastguard Worker // Inserts the least significant 32 bits of b into the selected 32-bit integer
7439*35ffd701SAndroid Build Coastguard Worker // of a.
7440*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_insert_epi32(__m128i a, int b,
7441*35ffd701SAndroid Build Coastguard Worker // __constrange(0,4) int imm)
7442*35ffd701SAndroid Build Coastguard Worker #define _mm_insert_epi32(a, b, imm) \
7443*35ffd701SAndroid Build Coastguard Worker __extension__({ \
7444*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s32( \
7445*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))); \
7446*35ffd701SAndroid Build Coastguard Worker })
7447*35ffd701SAndroid Build Coastguard Worker
7448*35ffd701SAndroid Build Coastguard Worker // Inserts the least significant 64 bits of b into the selected 64-bit integer
7449*35ffd701SAndroid Build Coastguard Worker // of a.
7450*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_insert_epi64(__m128i a, __int64 b,
7451*35ffd701SAndroid Build Coastguard Worker // __constrange(0,2) int imm)
7452*35ffd701SAndroid Build Coastguard Worker #define _mm_insert_epi64(a, b, imm) \
7453*35ffd701SAndroid Build Coastguard Worker __extension__({ \
7454*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s64( \
7455*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))); \
7456*35ffd701SAndroid Build Coastguard Worker })
7457*35ffd701SAndroid Build Coastguard Worker
7458*35ffd701SAndroid Build Coastguard Worker // Inserts the least significant 8 bits of b into the selected 8-bit integer
7459*35ffd701SAndroid Build Coastguard Worker // of a.
7460*35ffd701SAndroid Build Coastguard Worker // FORCE_INLINE __m128i _mm_insert_epi8(__m128i a, int b,
7461*35ffd701SAndroid Build Coastguard Worker // __constrange(0,16) int imm)
7462*35ffd701SAndroid Build Coastguard Worker #define _mm_insert_epi8(a, b, imm) \
7463*35ffd701SAndroid Build Coastguard Worker __extension__({ \
7464*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128i_s8( \
7465*35ffd701SAndroid Build Coastguard Worker vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))); \
7466*35ffd701SAndroid Build Coastguard Worker })
7467*35ffd701SAndroid Build Coastguard Worker
7468*35ffd701SAndroid Build Coastguard Worker // Copy a to tmp, then insert a single-precision (32-bit) floating-point
7469*35ffd701SAndroid Build Coastguard Worker // element from b into tmp using the control in imm8. Store tmp to dst using
7470*35ffd701SAndroid Build Coastguard Worker // the mask in imm8 (elements are zeroed out when the corresponding bit is set).
7471*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=insert_ps
7472*35ffd701SAndroid Build Coastguard Worker #define _mm_insert_ps(a, b, imm8) \
7473*35ffd701SAndroid Build Coastguard Worker __extension__({ \
7474*35ffd701SAndroid Build Coastguard Worker float32x4_t tmp1 = vsetq_lane_f32(vgetq_lane_f32(b, (imm >> 6) & 0x3), \
7475*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a), 0); \
7476*35ffd701SAndroid Build Coastguard Worker float32x4_t tmp2 = \
7477*35ffd701SAndroid Build Coastguard Worker vsetq_lane_f32(vgetq_lane_f32(tmp1, 0), vreinterpretq_f32_m128(a), \
7478*35ffd701SAndroid Build Coastguard Worker ((imm >> 4) & 0x3)); \
7479*35ffd701SAndroid Build Coastguard Worker const uint32_t data[4] = {((imm8) & (1 << 0)) ? UINT32_MAX : 0, \
7480*35ffd701SAndroid Build Coastguard Worker ((imm8) & (1 << 1)) ? UINT32_MAX : 0, \
7481*35ffd701SAndroid Build Coastguard Worker ((imm8) & (1 << 2)) ? UINT32_MAX : 0, \
7482*35ffd701SAndroid Build Coastguard Worker ((imm8) & (1 << 3)) ? UINT32_MAX : 0}; \
7483*35ffd701SAndroid Build Coastguard Worker uint32x4_t mask = vld1q_u32(data); \
7484*35ffd701SAndroid Build Coastguard Worker float32x4_t all_zeros = vdupq_n_f32(0); \
7485*35ffd701SAndroid Build Coastguard Worker \
7486*35ffd701SAndroid Build Coastguard Worker vreinterpretq_m128_f32( \
7487*35ffd701SAndroid Build Coastguard Worker vbslq_f32(mask, all_zeros, vreinterpretq_f32_m128(tmp2))); \
7488*35ffd701SAndroid Build Coastguard Worker })
7489*35ffd701SAndroid Build Coastguard Worker
7490*35ffd701SAndroid Build Coastguard Worker // epi versions of min/max
7491*35ffd701SAndroid Build Coastguard Worker // Computes the pariwise maximums of the four signed 32-bit integer values of a
7492*35ffd701SAndroid Build Coastguard Worker // and b.
7493*35ffd701SAndroid Build Coastguard Worker //
7494*35ffd701SAndroid Build Coastguard Worker // A 128-bit parameter that can be defined with the following equations:
7495*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 > b0) ? a0 : b0
7496*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 > b1) ? a1 : b1
7497*35ffd701SAndroid Build Coastguard Worker // r2 := (a2 > b2) ? a2 : b2
7498*35ffd701SAndroid Build Coastguard Worker // r3 := (a3 > b3) ? a3 : b3
7499*35ffd701SAndroid Build Coastguard Worker //
7500*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/bb514055(v=vs.100).aspx
_mm_max_epi32(__m128i a,__m128i b)7501*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_max_epi32(__m128i a, __m128i b)
7502*35ffd701SAndroid Build Coastguard Worker {
7503*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
7504*35ffd701SAndroid Build Coastguard Worker vmaxq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
7505*35ffd701SAndroid Build Coastguard Worker }
7506*35ffd701SAndroid Build Coastguard Worker
7507*35ffd701SAndroid Build Coastguard Worker // Compare packed signed 8-bit integers in a and b, and store packed maximum
7508*35ffd701SAndroid Build Coastguard Worker // values in dst.
7509*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epi8
_mm_max_epi8(__m128i a,__m128i b)7510*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_max_epi8(__m128i a, __m128i b)
7511*35ffd701SAndroid Build Coastguard Worker {
7512*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
7513*35ffd701SAndroid Build Coastguard Worker vmaxq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
7514*35ffd701SAndroid Build Coastguard Worker }
7515*35ffd701SAndroid Build Coastguard Worker
7516*35ffd701SAndroid Build Coastguard Worker // Compare packed unsigned 16-bit integers in a and b, and store packed maximum
7517*35ffd701SAndroid Build Coastguard Worker // values in dst.
7518*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu16
_mm_max_epu16(__m128i a,__m128i b)7519*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_max_epu16(__m128i a, __m128i b)
7520*35ffd701SAndroid Build Coastguard Worker {
7521*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(
7522*35ffd701SAndroid Build Coastguard Worker vmaxq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b)));
7523*35ffd701SAndroid Build Coastguard Worker }
7524*35ffd701SAndroid Build Coastguard Worker
7525*35ffd701SAndroid Build Coastguard Worker // Compare packed unsigned 32-bit integers in a and b, and store packed maximum
7526*35ffd701SAndroid Build Coastguard Worker // values in dst.
7527*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32
_mm_max_epu32(__m128i a,__m128i b)7528*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_max_epu32(__m128i a, __m128i b)
7529*35ffd701SAndroid Build Coastguard Worker {
7530*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u32(
7531*35ffd701SAndroid Build Coastguard Worker vmaxq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b)));
7532*35ffd701SAndroid Build Coastguard Worker }
7533*35ffd701SAndroid Build Coastguard Worker
7534*35ffd701SAndroid Build Coastguard Worker // Computes the pariwise minima of the four signed 32-bit integer values of a
7535*35ffd701SAndroid Build Coastguard Worker // and b.
7536*35ffd701SAndroid Build Coastguard Worker //
7537*35ffd701SAndroid Build Coastguard Worker // A 128-bit parameter that can be defined with the following equations:
7538*35ffd701SAndroid Build Coastguard Worker // r0 := (a0 < b0) ? a0 : b0
7539*35ffd701SAndroid Build Coastguard Worker // r1 := (a1 < b1) ? a1 : b1
7540*35ffd701SAndroid Build Coastguard Worker // r2 := (a2 < b2) ? a2 : b2
7541*35ffd701SAndroid Build Coastguard Worker // r3 := (a3 < b3) ? a3 : b3
7542*35ffd701SAndroid Build Coastguard Worker //
7543*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/bb531476(v=vs.100).aspx
_mm_min_epi32(__m128i a,__m128i b)7544*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b)
7545*35ffd701SAndroid Build Coastguard Worker {
7546*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
7547*35ffd701SAndroid Build Coastguard Worker vminq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
7548*35ffd701SAndroid Build Coastguard Worker }
7549*35ffd701SAndroid Build Coastguard Worker
7550*35ffd701SAndroid Build Coastguard Worker // Compare packed signed 8-bit integers in a and b, and store packed minimum
7551*35ffd701SAndroid Build Coastguard Worker // values in dst.
7552*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epi8
_mm_min_epi8(__m128i a,__m128i b)7553*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_min_epi8(__m128i a, __m128i b)
7554*35ffd701SAndroid Build Coastguard Worker {
7555*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s8(
7556*35ffd701SAndroid Build Coastguard Worker vminq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b)));
7557*35ffd701SAndroid Build Coastguard Worker }
7558*35ffd701SAndroid Build Coastguard Worker
7559*35ffd701SAndroid Build Coastguard Worker // Compare packed unsigned 16-bit integers in a and b, and store packed minimum
7560*35ffd701SAndroid Build Coastguard Worker // values in dst.
7561*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epu16
_mm_min_epu16(__m128i a,__m128i b)7562*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_min_epu16(__m128i a, __m128i b)
7563*35ffd701SAndroid Build Coastguard Worker {
7564*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(
7565*35ffd701SAndroid Build Coastguard Worker vminq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b)));
7566*35ffd701SAndroid Build Coastguard Worker }
7567*35ffd701SAndroid Build Coastguard Worker
7568*35ffd701SAndroid Build Coastguard Worker // Compare packed unsigned 32-bit integers in a and b, and store packed minimum
7569*35ffd701SAndroid Build Coastguard Worker // values in dst.
7570*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32
_mm_min_epu32(__m128i a,__m128i b)7571*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_min_epu32(__m128i a, __m128i b)
7572*35ffd701SAndroid Build Coastguard Worker {
7573*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u32(
7574*35ffd701SAndroid Build Coastguard Worker vminq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b)));
7575*35ffd701SAndroid Build Coastguard Worker }
7576*35ffd701SAndroid Build Coastguard Worker
7577*35ffd701SAndroid Build Coastguard Worker // Horizontally compute the minimum amongst the packed unsigned 16-bit integers
7578*35ffd701SAndroid Build Coastguard Worker // in a, store the minimum and index in dst, and zero the remaining bits in dst.
7579*35ffd701SAndroid Build Coastguard Worker //
7580*35ffd701SAndroid Build Coastguard Worker // index[2:0] := 0
7581*35ffd701SAndroid Build Coastguard Worker // min[15:0] := a[15:0]
7582*35ffd701SAndroid Build Coastguard Worker // FOR j := 0 to 7
7583*35ffd701SAndroid Build Coastguard Worker // i := j*16
7584*35ffd701SAndroid Build Coastguard Worker // IF a[i+15:i] < min[15:0]
7585*35ffd701SAndroid Build Coastguard Worker // index[2:0] := j
7586*35ffd701SAndroid Build Coastguard Worker // min[15:0] := a[i+15:i]
7587*35ffd701SAndroid Build Coastguard Worker // FI
7588*35ffd701SAndroid Build Coastguard Worker // ENDFOR
7589*35ffd701SAndroid Build Coastguard Worker // dst[15:0] := min[15:0]
7590*35ffd701SAndroid Build Coastguard Worker // dst[18:16] := index[2:0]
7591*35ffd701SAndroid Build Coastguard Worker // dst[127:19] := 0
7592*35ffd701SAndroid Build Coastguard Worker //
7593*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_minpos_epu16
_mm_minpos_epu16(__m128i a)7594*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_minpos_epu16(__m128i a)
7595*35ffd701SAndroid Build Coastguard Worker {
7596*35ffd701SAndroid Build Coastguard Worker __m128i dst;
7597*35ffd701SAndroid Build Coastguard Worker uint16_t min, idx = 0;
7598*35ffd701SAndroid Build Coastguard Worker // Find the minimum value
7599*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7600*35ffd701SAndroid Build Coastguard Worker min = vminvq_u16(vreinterpretq_u16_m128i(a));
7601*35ffd701SAndroid Build Coastguard Worker #else
7602*35ffd701SAndroid Build Coastguard Worker __m64 tmp;
7603*35ffd701SAndroid Build Coastguard Worker tmp = vreinterpret_m64_u16(
7604*35ffd701SAndroid Build Coastguard Worker vmin_u16(vget_low_u16(vreinterpretq_u16_m128i(a)),
7605*35ffd701SAndroid Build Coastguard Worker vget_high_u16(vreinterpretq_u16_m128i(a))));
7606*35ffd701SAndroid Build Coastguard Worker tmp = vreinterpret_m64_u16(
7607*35ffd701SAndroid Build Coastguard Worker vpmin_u16(vreinterpret_u16_m64(tmp), vreinterpret_u16_m64(tmp)));
7608*35ffd701SAndroid Build Coastguard Worker tmp = vreinterpret_m64_u16(
7609*35ffd701SAndroid Build Coastguard Worker vpmin_u16(vreinterpret_u16_m64(tmp), vreinterpret_u16_m64(tmp)));
7610*35ffd701SAndroid Build Coastguard Worker min = vget_lane_u16(vreinterpret_u16_m64(tmp), 0);
7611*35ffd701SAndroid Build Coastguard Worker #endif
7612*35ffd701SAndroid Build Coastguard Worker // Get the index of the minimum value
7613*35ffd701SAndroid Build Coastguard Worker int i;
7614*35ffd701SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
7615*35ffd701SAndroid Build Coastguard Worker if (min == vgetq_lane_u16(vreinterpretq_u16_m128i(a), 0)) {
7616*35ffd701SAndroid Build Coastguard Worker idx = (uint16_t) i;
7617*35ffd701SAndroid Build Coastguard Worker break;
7618*35ffd701SAndroid Build Coastguard Worker }
7619*35ffd701SAndroid Build Coastguard Worker a = _mm_srli_si128(a, 2);
7620*35ffd701SAndroid Build Coastguard Worker }
7621*35ffd701SAndroid Build Coastguard Worker // Generate result
7622*35ffd701SAndroid Build Coastguard Worker dst = _mm_setzero_si128();
7623*35ffd701SAndroid Build Coastguard Worker dst = vreinterpretq_m128i_u16(
7624*35ffd701SAndroid Build Coastguard Worker vsetq_lane_u16(min, vreinterpretq_u16_m128i(dst), 0));
7625*35ffd701SAndroid Build Coastguard Worker dst = vreinterpretq_m128i_u16(
7626*35ffd701SAndroid Build Coastguard Worker vsetq_lane_u16(idx, vreinterpretq_u16_m128i(dst), 1));
7627*35ffd701SAndroid Build Coastguard Worker return dst;
7628*35ffd701SAndroid Build Coastguard Worker }
7629*35ffd701SAndroid Build Coastguard Worker
7630*35ffd701SAndroid Build Coastguard Worker // Multiply the low signed 32-bit integers from each packed 64-bit element in
7631*35ffd701SAndroid Build Coastguard Worker // a and b, and store the signed 64-bit results in dst.
7632*35ffd701SAndroid Build Coastguard Worker //
7633*35ffd701SAndroid Build Coastguard Worker // r0 := (int64_t)(int32_t)a0 * (int64_t)(int32_t)b0
7634*35ffd701SAndroid Build Coastguard Worker // r1 := (int64_t)(int32_t)a2 * (int64_t)(int32_t)b2
_mm_mul_epi32(__m128i a,__m128i b)7635*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_mul_epi32(__m128i a, __m128i b)
7636*35ffd701SAndroid Build Coastguard Worker {
7637*35ffd701SAndroid Build Coastguard Worker // vmull_s32 upcasts instead of masking, so we downcast.
7638*35ffd701SAndroid Build Coastguard Worker int32x2_t a_lo = vmovn_s64(vreinterpretq_s64_m128i(a));
7639*35ffd701SAndroid Build Coastguard Worker int32x2_t b_lo = vmovn_s64(vreinterpretq_s64_m128i(b));
7640*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vmull_s32(a_lo, b_lo));
7641*35ffd701SAndroid Build Coastguard Worker }
7642*35ffd701SAndroid Build Coastguard Worker
7643*35ffd701SAndroid Build Coastguard Worker // Multiplies the 4 signed or unsigned 32-bit integers from a by the 4 signed or
7644*35ffd701SAndroid Build Coastguard Worker // unsigned 32-bit integers from b.
7645*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/vstudio/bb531409(v=vs.100).aspx
_mm_mullo_epi32(__m128i a,__m128i b)7646*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_mullo_epi32(__m128i a, __m128i b)
7647*35ffd701SAndroid Build Coastguard Worker {
7648*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s32(
7649*35ffd701SAndroid Build Coastguard Worker vmulq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b)));
7650*35ffd701SAndroid Build Coastguard Worker }
7651*35ffd701SAndroid Build Coastguard Worker
7652*35ffd701SAndroid Build Coastguard Worker // Packs the 8 unsigned 32-bit integers from a and b into unsigned 16-bit
7653*35ffd701SAndroid Build Coastguard Worker // integers and saturates.
7654*35ffd701SAndroid Build Coastguard Worker //
7655*35ffd701SAndroid Build Coastguard Worker // r0 := UnsignedSaturate(a0)
7656*35ffd701SAndroid Build Coastguard Worker // r1 := UnsignedSaturate(a1)
7657*35ffd701SAndroid Build Coastguard Worker // r2 := UnsignedSaturate(a2)
7658*35ffd701SAndroid Build Coastguard Worker // r3 := UnsignedSaturate(a3)
7659*35ffd701SAndroid Build Coastguard Worker // r4 := UnsignedSaturate(b0)
7660*35ffd701SAndroid Build Coastguard Worker // r5 := UnsignedSaturate(b1)
7661*35ffd701SAndroid Build Coastguard Worker // r6 := UnsignedSaturate(b2)
7662*35ffd701SAndroid Build Coastguard Worker // r7 := UnsignedSaturate(b3)
_mm_packus_epi32(__m128i a,__m128i b)7663*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b)
7664*35ffd701SAndroid Build Coastguard Worker {
7665*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u16(
7666*35ffd701SAndroid Build Coastguard Worker vcombine_u16(vqmovun_s32(vreinterpretq_s32_m128i(a)),
7667*35ffd701SAndroid Build Coastguard Worker vqmovun_s32(vreinterpretq_s32_m128i(b))));
7668*35ffd701SAndroid Build Coastguard Worker }
7669*35ffd701SAndroid Build Coastguard Worker
7670*35ffd701SAndroid Build Coastguard Worker // Round the packed double-precision (64-bit) floating-point elements in a using
7671*35ffd701SAndroid Build Coastguard Worker // the rounding parameter, and store the results as packed double-precision
7672*35ffd701SAndroid Build Coastguard Worker // floating-point elements in dst.
7673*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_pd
_mm_round_pd(__m128d a,int rounding)7674*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_round_pd(__m128d a, int rounding)
7675*35ffd701SAndroid Build Coastguard Worker {
7676*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7677*35ffd701SAndroid Build Coastguard Worker switch (rounding) {
7678*35ffd701SAndroid Build Coastguard Worker case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC):
7679*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vrndnq_f64(vreinterpretq_f64_m128d(a)));
7680*35ffd701SAndroid Build Coastguard Worker case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC):
7681*35ffd701SAndroid Build Coastguard Worker return _mm_floor_pd(a);
7682*35ffd701SAndroid Build Coastguard Worker case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC):
7683*35ffd701SAndroid Build Coastguard Worker return _mm_ceil_pd(a);
7684*35ffd701SAndroid Build Coastguard Worker case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC):
7685*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vrndq_f64(vreinterpretq_f64_m128d(a)));
7686*35ffd701SAndroid Build Coastguard Worker default: //_MM_FROUND_CUR_DIRECTION
7687*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128d_f64(vrndiq_f64(vreinterpretq_f64_m128d(a)));
7688*35ffd701SAndroid Build Coastguard Worker }
7689*35ffd701SAndroid Build Coastguard Worker #else
7690*35ffd701SAndroid Build Coastguard Worker double *v_double = (double *) &a;
7691*35ffd701SAndroid Build Coastguard Worker
7692*35ffd701SAndroid Build Coastguard Worker if (rounding == (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC) ||
7693*35ffd701SAndroid Build Coastguard Worker (rounding == _MM_FROUND_CUR_DIRECTION &&
7694*35ffd701SAndroid Build Coastguard Worker _MM_GET_ROUNDING_MODE() == _MM_ROUND_NEAREST)) {
7695*35ffd701SAndroid Build Coastguard Worker double res[2], tmp;
7696*35ffd701SAndroid Build Coastguard Worker for (int i = 0; i < 2; i++) {
7697*35ffd701SAndroid Build Coastguard Worker tmp = (v_double[i] < 0) ? -v_double[i] : v_double[i];
7698*35ffd701SAndroid Build Coastguard Worker double roundDown = floor(tmp); // Round down value
7699*35ffd701SAndroid Build Coastguard Worker double roundUp = ceil(tmp); // Round up value
7700*35ffd701SAndroid Build Coastguard Worker double diffDown = tmp - roundDown;
7701*35ffd701SAndroid Build Coastguard Worker double diffUp = roundUp - tmp;
7702*35ffd701SAndroid Build Coastguard Worker if (diffDown < diffUp) {
7703*35ffd701SAndroid Build Coastguard Worker /* If it's closer to the round down value, then use it */
7704*35ffd701SAndroid Build Coastguard Worker res[i] = roundDown;
7705*35ffd701SAndroid Build Coastguard Worker } else if (diffDown > diffUp) {
7706*35ffd701SAndroid Build Coastguard Worker /* If it's closer to the round up value, then use it */
7707*35ffd701SAndroid Build Coastguard Worker res[i] = roundUp;
7708*35ffd701SAndroid Build Coastguard Worker } else {
7709*35ffd701SAndroid Build Coastguard Worker /* If it's equidistant between round up and round down value,
7710*35ffd701SAndroid Build Coastguard Worker * pick the one which is an even number */
7711*35ffd701SAndroid Build Coastguard Worker double half = roundDown / 2;
7712*35ffd701SAndroid Build Coastguard Worker if (half != floor(half)) {
7713*35ffd701SAndroid Build Coastguard Worker /* If the round down value is odd, return the round up value
7714*35ffd701SAndroid Build Coastguard Worker */
7715*35ffd701SAndroid Build Coastguard Worker res[i] = roundUp;
7716*35ffd701SAndroid Build Coastguard Worker } else {
7717*35ffd701SAndroid Build Coastguard Worker /* If the round up value is odd, return the round down value
7718*35ffd701SAndroid Build Coastguard Worker */
7719*35ffd701SAndroid Build Coastguard Worker res[i] = roundDown;
7720*35ffd701SAndroid Build Coastguard Worker }
7721*35ffd701SAndroid Build Coastguard Worker }
7722*35ffd701SAndroid Build Coastguard Worker res[i] = (v_double[i] < 0) ? -res[i] : res[i];
7723*35ffd701SAndroid Build Coastguard Worker }
7724*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(res[1], res[0]);
7725*35ffd701SAndroid Build Coastguard Worker } else if (rounding == (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC) ||
7726*35ffd701SAndroid Build Coastguard Worker (rounding == _MM_FROUND_CUR_DIRECTION &&
7727*35ffd701SAndroid Build Coastguard Worker _MM_GET_ROUNDING_MODE() == _MM_ROUND_DOWN)) {
7728*35ffd701SAndroid Build Coastguard Worker return _mm_floor_pd(a);
7729*35ffd701SAndroid Build Coastguard Worker } else if (rounding == (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC) ||
7730*35ffd701SAndroid Build Coastguard Worker (rounding == _MM_FROUND_CUR_DIRECTION &&
7731*35ffd701SAndroid Build Coastguard Worker _MM_GET_ROUNDING_MODE() == _MM_ROUND_UP)) {
7732*35ffd701SAndroid Build Coastguard Worker return _mm_ceil_pd(a);
7733*35ffd701SAndroid Build Coastguard Worker }
7734*35ffd701SAndroid Build Coastguard Worker return _mm_set_pd(v_double[1] > 0 ? floor(v_double[1]) : ceil(v_double[1]),
7735*35ffd701SAndroid Build Coastguard Worker v_double[0] > 0 ? floor(v_double[0]) : ceil(v_double[0]));
7736*35ffd701SAndroid Build Coastguard Worker #endif
7737*35ffd701SAndroid Build Coastguard Worker }
7738*35ffd701SAndroid Build Coastguard Worker
7739*35ffd701SAndroid Build Coastguard Worker // Round the packed single-precision (32-bit) floating-point elements in a using
7740*35ffd701SAndroid Build Coastguard Worker // the rounding parameter, and store the results as packed single-precision
7741*35ffd701SAndroid Build Coastguard Worker // floating-point elements in dst.
7742*35ffd701SAndroid Build Coastguard Worker // software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ps
_mm_round_ps(__m128 a,int rounding)7743*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_round_ps(__m128 a, int rounding)
7744*35ffd701SAndroid Build Coastguard Worker {
7745*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7746*35ffd701SAndroid Build Coastguard Worker switch (rounding) {
7747*35ffd701SAndroid Build Coastguard Worker case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC):
7748*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vrndnq_f32(vreinterpretq_f32_m128(a)));
7749*35ffd701SAndroid Build Coastguard Worker case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC):
7750*35ffd701SAndroid Build Coastguard Worker return _mm_floor_ps(a);
7751*35ffd701SAndroid Build Coastguard Worker case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC):
7752*35ffd701SAndroid Build Coastguard Worker return _mm_ceil_ps(a);
7753*35ffd701SAndroid Build Coastguard Worker case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC):
7754*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vrndq_f32(vreinterpretq_f32_m128(a)));
7755*35ffd701SAndroid Build Coastguard Worker default: //_MM_FROUND_CUR_DIRECTION
7756*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(vrndiq_f32(vreinterpretq_f32_m128(a)));
7757*35ffd701SAndroid Build Coastguard Worker }
7758*35ffd701SAndroid Build Coastguard Worker #else
7759*35ffd701SAndroid Build Coastguard Worker float *v_float = (float *) &a;
7760*35ffd701SAndroid Build Coastguard Worker
7761*35ffd701SAndroid Build Coastguard Worker if (rounding == (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC) ||
7762*35ffd701SAndroid Build Coastguard Worker (rounding == _MM_FROUND_CUR_DIRECTION &&
7763*35ffd701SAndroid Build Coastguard Worker _MM_GET_ROUNDING_MODE() == _MM_ROUND_NEAREST)) {
7764*35ffd701SAndroid Build Coastguard Worker uint32x4_t signmask = vdupq_n_u32(0x80000000);
7765*35ffd701SAndroid Build Coastguard Worker float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a),
7766*35ffd701SAndroid Build Coastguard Worker vdupq_n_f32(0.5f)); /* +/- 0.5 */
7767*35ffd701SAndroid Build Coastguard Worker int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32(
7768*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/
7769*35ffd701SAndroid Build Coastguard Worker int32x4_t r_trunc = vcvtq_s32_f32(
7770*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */
7771*35ffd701SAndroid Build Coastguard Worker int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32(
7772*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */
7773*35ffd701SAndroid Build Coastguard Worker int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone),
7774*35ffd701SAndroid Build Coastguard Worker vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */
7775*35ffd701SAndroid Build Coastguard Worker float32x4_t delta = vsubq_f32(
7776*35ffd701SAndroid Build Coastguard Worker vreinterpretq_f32_m128(a),
7777*35ffd701SAndroid Build Coastguard Worker vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */
7778*35ffd701SAndroid Build Coastguard Worker uint32x4_t is_delta_half =
7779*35ffd701SAndroid Build Coastguard Worker vceqq_f32(delta, half); /* delta == +/- 0.5 */
7780*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128_f32(
7781*35ffd701SAndroid Build Coastguard Worker vcvtq_f32_s32(vbslq_s32(is_delta_half, r_even, r_normal)));
7782*35ffd701SAndroid Build Coastguard Worker } else if (rounding == (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC) ||
7783*35ffd701SAndroid Build Coastguard Worker (rounding == _MM_FROUND_CUR_DIRECTION &&
7784*35ffd701SAndroid Build Coastguard Worker _MM_GET_ROUNDING_MODE() == _MM_ROUND_DOWN)) {
7785*35ffd701SAndroid Build Coastguard Worker return _mm_floor_ps(a);
7786*35ffd701SAndroid Build Coastguard Worker } else if (rounding == (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC) ||
7787*35ffd701SAndroid Build Coastguard Worker (rounding == _MM_FROUND_CUR_DIRECTION &&
7788*35ffd701SAndroid Build Coastguard Worker _MM_GET_ROUNDING_MODE() == _MM_ROUND_UP)) {
7789*35ffd701SAndroid Build Coastguard Worker return _mm_ceil_ps(a);
7790*35ffd701SAndroid Build Coastguard Worker }
7791*35ffd701SAndroid Build Coastguard Worker return _mm_set_ps(v_float[3] > 0 ? floorf(v_float[3]) : ceilf(v_float[3]),
7792*35ffd701SAndroid Build Coastguard Worker v_float[2] > 0 ? floorf(v_float[2]) : ceilf(v_float[2]),
7793*35ffd701SAndroid Build Coastguard Worker v_float[1] > 0 ? floorf(v_float[1]) : ceilf(v_float[1]),
7794*35ffd701SAndroid Build Coastguard Worker v_float[0] > 0 ? floorf(v_float[0]) : ceilf(v_float[0]));
7795*35ffd701SAndroid Build Coastguard Worker #endif
7796*35ffd701SAndroid Build Coastguard Worker }
7797*35ffd701SAndroid Build Coastguard Worker
7798*35ffd701SAndroid Build Coastguard Worker // Round the lower double-precision (64-bit) floating-point element in b using
7799*35ffd701SAndroid Build Coastguard Worker // the rounding parameter, store the result as a double-precision floating-point
7800*35ffd701SAndroid Build Coastguard Worker // element in the lower element of dst, and copy the upper element from a to the
7801*35ffd701SAndroid Build Coastguard Worker // upper element of dst.
7802*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_sd
_mm_round_sd(__m128d a,__m128d b,int rounding)7803*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128d _mm_round_sd(__m128d a, __m128d b, int rounding)
7804*35ffd701SAndroid Build Coastguard Worker {
7805*35ffd701SAndroid Build Coastguard Worker return _mm_move_sd(a, _mm_round_pd(b, rounding));
7806*35ffd701SAndroid Build Coastguard Worker }
7807*35ffd701SAndroid Build Coastguard Worker
7808*35ffd701SAndroid Build Coastguard Worker // Round the lower single-precision (32-bit) floating-point element in b using
7809*35ffd701SAndroid Build Coastguard Worker // the rounding parameter, store the result as a single-precision floating-point
7810*35ffd701SAndroid Build Coastguard Worker // element in the lower element of dst, and copy the upper 3 packed elements
7811*35ffd701SAndroid Build Coastguard Worker // from a to the upper elements of dst. Rounding is done according to the
7812*35ffd701SAndroid Build Coastguard Worker // rounding[3:0] parameter, which can be one of:
7813*35ffd701SAndroid Build Coastguard Worker // (_MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC) // round to nearest, and
7814*35ffd701SAndroid Build Coastguard Worker // suppress exceptions
7815*35ffd701SAndroid Build Coastguard Worker // (_MM_FROUND_TO_NEG_INF |_MM_FROUND_NO_EXC) // round down, and
7816*35ffd701SAndroid Build Coastguard Worker // suppress exceptions
7817*35ffd701SAndroid Build Coastguard Worker // (_MM_FROUND_TO_POS_INF |_MM_FROUND_NO_EXC) // round up, and suppress
7818*35ffd701SAndroid Build Coastguard Worker // exceptions
7819*35ffd701SAndroid Build Coastguard Worker // (_MM_FROUND_TO_ZERO |_MM_FROUND_NO_EXC) // truncate, and suppress
7820*35ffd701SAndroid Build Coastguard Worker // exceptions _MM_FROUND_CUR_DIRECTION // use MXCSR.RC; see
7821*35ffd701SAndroid Build Coastguard Worker // _MM_SET_ROUNDING_MODE
7822*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ss
_mm_round_ss(__m128 a,__m128 b,int rounding)7823*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128 _mm_round_ss(__m128 a, __m128 b, int rounding)
7824*35ffd701SAndroid Build Coastguard Worker {
7825*35ffd701SAndroid Build Coastguard Worker return _mm_move_ss(a, _mm_round_ps(b, rounding));
7826*35ffd701SAndroid Build Coastguard Worker }
7827*35ffd701SAndroid Build Coastguard Worker
7828*35ffd701SAndroid Build Coastguard Worker // Load 128-bits of integer data from memory into dst using a non-temporal
7829*35ffd701SAndroid Build Coastguard Worker // memory hint. mem_addr must be aligned on a 16-byte boundary or a
7830*35ffd701SAndroid Build Coastguard Worker // general-protection exception may be generated.
7831*35ffd701SAndroid Build Coastguard Worker //
7832*35ffd701SAndroid Build Coastguard Worker // dst[127:0] := MEM[mem_addr+127:mem_addr]
7833*35ffd701SAndroid Build Coastguard Worker //
7834*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_load_si128
_mm_stream_load_si128(__m128i * p)7835*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_stream_load_si128(__m128i *p)
7836*35ffd701SAndroid Build Coastguard Worker {
7837*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_nontemporal_store)
7838*35ffd701SAndroid Build Coastguard Worker return __builtin_nontemporal_load(p);
7839*35ffd701SAndroid Build Coastguard Worker #else
7840*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vld1q_s64((int64_t *) p));
7841*35ffd701SAndroid Build Coastguard Worker #endif
7842*35ffd701SAndroid Build Coastguard Worker }
7843*35ffd701SAndroid Build Coastguard Worker
7844*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise NOT of a and then AND with a 128-bit vector containing
7845*35ffd701SAndroid Build Coastguard Worker // all 1's, and return 1 if the result is zero, otherwise return 0.
7846*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_ones
_mm_test_all_ones(__m128i a)7847*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_test_all_ones(__m128i a)
7848*35ffd701SAndroid Build Coastguard Worker {
7849*35ffd701SAndroid Build Coastguard Worker return (uint64_t)(vgetq_lane_s64(a, 0) & vgetq_lane_s64(a, 1)) ==
7850*35ffd701SAndroid Build Coastguard Worker ~(uint64_t) 0;
7851*35ffd701SAndroid Build Coastguard Worker }
7852*35ffd701SAndroid Build Coastguard Worker
7853*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise AND of 128 bits (representing integer data) in a and
7854*35ffd701SAndroid Build Coastguard Worker // mask, and return 1 if the result is zero, otherwise return 0.
7855*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_zeros
_mm_test_all_zeros(__m128i a,__m128i mask)7856*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_test_all_zeros(__m128i a, __m128i mask)
7857*35ffd701SAndroid Build Coastguard Worker {
7858*35ffd701SAndroid Build Coastguard Worker int64x2_t a_and_mask =
7859*35ffd701SAndroid Build Coastguard Worker vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(mask));
7860*35ffd701SAndroid Build Coastguard Worker return !(vgetq_lane_s64(a_and_mask, 0) | vgetq_lane_s64(a_and_mask, 1));
7861*35ffd701SAndroid Build Coastguard Worker }
7862*35ffd701SAndroid Build Coastguard Worker
7863*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise AND of 128 bits (representing integer data) in a and
7864*35ffd701SAndroid Build Coastguard Worker // mask, and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute
7865*35ffd701SAndroid Build Coastguard Worker // the bitwise NOT of a and then AND with mask, and set CF to 1 if the result is
7866*35ffd701SAndroid Build Coastguard Worker // zero, otherwise set CF to 0. Return 1 if both the ZF and CF values are zero,
7867*35ffd701SAndroid Build Coastguard Worker // otherwise return 0.
7868*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_test_mix_ones_zero
_mm_test_mix_ones_zeros(__m128i a,__m128i mask)7869*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_test_mix_ones_zeros(__m128i a, __m128i mask)
7870*35ffd701SAndroid Build Coastguard Worker {
7871*35ffd701SAndroid Build Coastguard Worker uint64x2_t zf =
7872*35ffd701SAndroid Build Coastguard Worker vandq_u64(vreinterpretq_u64_m128i(mask), vreinterpretq_u64_m128i(a));
7873*35ffd701SAndroid Build Coastguard Worker uint64x2_t cf =
7874*35ffd701SAndroid Build Coastguard Worker vbicq_u64(vreinterpretq_u64_m128i(mask), vreinterpretq_u64_m128i(a));
7875*35ffd701SAndroid Build Coastguard Worker uint64x2_t result = vandq_u64(zf, cf);
7876*35ffd701SAndroid Build Coastguard Worker return !(vgetq_lane_u64(result, 0) | vgetq_lane_u64(result, 1));
7877*35ffd701SAndroid Build Coastguard Worker }
7878*35ffd701SAndroid Build Coastguard Worker
7879*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise AND of 128 bits (representing integer data) in a and b,
7880*35ffd701SAndroid Build Coastguard Worker // and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the
7881*35ffd701SAndroid Build Coastguard Worker // bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero,
7882*35ffd701SAndroid Build Coastguard Worker // otherwise set CF to 0. Return the CF value.
7883*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testc_si128
_mm_testc_si128(__m128i a,__m128i b)7884*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_testc_si128(__m128i a, __m128i b)
7885*35ffd701SAndroid Build Coastguard Worker {
7886*35ffd701SAndroid Build Coastguard Worker int64x2_t s64 =
7887*35ffd701SAndroid Build Coastguard Worker vandq_s64(vreinterpretq_s64_s32(vmvnq_s32(vreinterpretq_s32_m128i(a))),
7888*35ffd701SAndroid Build Coastguard Worker vreinterpretq_s64_m128i(b));
7889*35ffd701SAndroid Build Coastguard Worker return !(vgetq_lane_s64(s64, 0) | vgetq_lane_s64(s64, 1));
7890*35ffd701SAndroid Build Coastguard Worker }
7891*35ffd701SAndroid Build Coastguard Worker
7892*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise AND of 128 bits (representing integer data) in a and b,
7893*35ffd701SAndroid Build Coastguard Worker // and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the
7894*35ffd701SAndroid Build Coastguard Worker // bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero,
7895*35ffd701SAndroid Build Coastguard Worker // otherwise set CF to 0. Return 1 if both the ZF and CF values are zero,
7896*35ffd701SAndroid Build Coastguard Worker // otherwise return 0.
7897*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testnzc_si128
7898*35ffd701SAndroid Build Coastguard Worker #define _mm_testnzc_si128(a, b) _mm_test_mix_ones_zeros(a, b)
7899*35ffd701SAndroid Build Coastguard Worker
7900*35ffd701SAndroid Build Coastguard Worker // Compute the bitwise AND of 128 bits (representing integer data) in a and b,
7901*35ffd701SAndroid Build Coastguard Worker // and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the
7902*35ffd701SAndroid Build Coastguard Worker // bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero,
7903*35ffd701SAndroid Build Coastguard Worker // otherwise set CF to 0. Return the ZF value.
7904*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testz_si128
_mm_testz_si128(__m128i a,__m128i b)7905*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_testz_si128(__m128i a, __m128i b)
7906*35ffd701SAndroid Build Coastguard Worker {
7907*35ffd701SAndroid Build Coastguard Worker int64x2_t s64 =
7908*35ffd701SAndroid Build Coastguard Worker vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b));
7909*35ffd701SAndroid Build Coastguard Worker return !(vgetq_lane_s64(s64, 0) | vgetq_lane_s64(s64, 1));
7910*35ffd701SAndroid Build Coastguard Worker }
7911*35ffd701SAndroid Build Coastguard Worker
7912*35ffd701SAndroid Build Coastguard Worker /* SSE4.2 */
7913*35ffd701SAndroid Build Coastguard Worker
7914*35ffd701SAndroid Build Coastguard Worker // Compares the 2 signed 64-bit integers in a and the 2 signed 64-bit integers
7915*35ffd701SAndroid Build Coastguard Worker // in b for greater than.
_mm_cmpgt_epi64(__m128i a,__m128i b)7916*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b)
7917*35ffd701SAndroid Build Coastguard Worker {
7918*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
7919*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(
7920*35ffd701SAndroid Build Coastguard Worker vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b)));
7921*35ffd701SAndroid Build Coastguard Worker #else
7922*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_s64(vshrq_n_s64(
7923*35ffd701SAndroid Build Coastguard Worker vqsubq_s64(vreinterpretq_s64_m128i(b), vreinterpretq_s64_m128i(a)),
7924*35ffd701SAndroid Build Coastguard Worker 63));
7925*35ffd701SAndroid Build Coastguard Worker #endif
7926*35ffd701SAndroid Build Coastguard Worker }
7927*35ffd701SAndroid Build Coastguard Worker
7928*35ffd701SAndroid Build Coastguard Worker // Starting with the initial value in crc, accumulates a CRC32 value for
7929*35ffd701SAndroid Build Coastguard Worker // unsigned 16-bit integer v.
7930*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/bb531411(v=vs.100)
_mm_crc32_u16(uint32_t crc,uint16_t v)7931*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE uint32_t _mm_crc32_u16(uint32_t crc, uint16_t v)
7932*35ffd701SAndroid Build Coastguard Worker {
7933*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
7934*35ffd701SAndroid Build Coastguard Worker __asm__ __volatile__("crc32ch %w[c], %w[c], %w[v]\n\t"
7935*35ffd701SAndroid Build Coastguard Worker : [c] "+r"(crc)
7936*35ffd701SAndroid Build Coastguard Worker : [v] "r"(v));
7937*35ffd701SAndroid Build Coastguard Worker #else
7938*35ffd701SAndroid Build Coastguard Worker crc = _mm_crc32_u8(crc, v & 0xff);
7939*35ffd701SAndroid Build Coastguard Worker crc = _mm_crc32_u8(crc, (v >> 8) & 0xff);
7940*35ffd701SAndroid Build Coastguard Worker #endif
7941*35ffd701SAndroid Build Coastguard Worker return crc;
7942*35ffd701SAndroid Build Coastguard Worker }
7943*35ffd701SAndroid Build Coastguard Worker
7944*35ffd701SAndroid Build Coastguard Worker // Starting with the initial value in crc, accumulates a CRC32 value for
7945*35ffd701SAndroid Build Coastguard Worker // unsigned 32-bit integer v.
7946*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/bb531394(v=vs.100)
_mm_crc32_u32(uint32_t crc,uint32_t v)7947*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE uint32_t _mm_crc32_u32(uint32_t crc, uint32_t v)
7948*35ffd701SAndroid Build Coastguard Worker {
7949*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
7950*35ffd701SAndroid Build Coastguard Worker __asm__ __volatile__("crc32cw %w[c], %w[c], %w[v]\n\t"
7951*35ffd701SAndroid Build Coastguard Worker : [c] "+r"(crc)
7952*35ffd701SAndroid Build Coastguard Worker : [v] "r"(v));
7953*35ffd701SAndroid Build Coastguard Worker #else
7954*35ffd701SAndroid Build Coastguard Worker crc = _mm_crc32_u16(crc, v & 0xffff);
7955*35ffd701SAndroid Build Coastguard Worker crc = _mm_crc32_u16(crc, (v >> 16) & 0xffff);
7956*35ffd701SAndroid Build Coastguard Worker #endif
7957*35ffd701SAndroid Build Coastguard Worker return crc;
7958*35ffd701SAndroid Build Coastguard Worker }
7959*35ffd701SAndroid Build Coastguard Worker
7960*35ffd701SAndroid Build Coastguard Worker // Starting with the initial value in crc, accumulates a CRC32 value for
7961*35ffd701SAndroid Build Coastguard Worker // unsigned 64-bit integer v.
7962*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/bb514033(v=vs.100)
_mm_crc32_u64(uint64_t crc,uint64_t v)7963*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE uint64_t _mm_crc32_u64(uint64_t crc, uint64_t v)
7964*35ffd701SAndroid Build Coastguard Worker {
7965*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
7966*35ffd701SAndroid Build Coastguard Worker __asm__ __volatile__("crc32cx %w[c], %w[c], %x[v]\n\t"
7967*35ffd701SAndroid Build Coastguard Worker : [c] "+r"(crc)
7968*35ffd701SAndroid Build Coastguard Worker : [v] "r"(v));
7969*35ffd701SAndroid Build Coastguard Worker #else
7970*35ffd701SAndroid Build Coastguard Worker crc = _mm_crc32_u32((uint32_t)(crc), v & 0xffffffff);
7971*35ffd701SAndroid Build Coastguard Worker crc = _mm_crc32_u32((uint32_t)(crc), (v >> 32) & 0xffffffff);
7972*35ffd701SAndroid Build Coastguard Worker #endif
7973*35ffd701SAndroid Build Coastguard Worker return crc;
7974*35ffd701SAndroid Build Coastguard Worker }
7975*35ffd701SAndroid Build Coastguard Worker
7976*35ffd701SAndroid Build Coastguard Worker // Starting with the initial value in crc, accumulates a CRC32 value for
7977*35ffd701SAndroid Build Coastguard Worker // unsigned 8-bit integer v.
7978*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/bb514036(v=vs.100)
_mm_crc32_u8(uint32_t crc,uint8_t v)7979*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t crc, uint8_t v)
7980*35ffd701SAndroid Build Coastguard Worker {
7981*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
7982*35ffd701SAndroid Build Coastguard Worker __asm__ __volatile__("crc32cb %w[c], %w[c], %w[v]\n\t"
7983*35ffd701SAndroid Build Coastguard Worker : [c] "+r"(crc)
7984*35ffd701SAndroid Build Coastguard Worker : [v] "r"(v));
7985*35ffd701SAndroid Build Coastguard Worker #else
7986*35ffd701SAndroid Build Coastguard Worker crc ^= v;
7987*35ffd701SAndroid Build Coastguard Worker for (int bit = 0; bit < 8; bit++) {
7988*35ffd701SAndroid Build Coastguard Worker if (crc & 1)
7989*35ffd701SAndroid Build Coastguard Worker crc = (crc >> 1) ^ UINT32_C(0x82f63b78);
7990*35ffd701SAndroid Build Coastguard Worker else
7991*35ffd701SAndroid Build Coastguard Worker crc = (crc >> 1);
7992*35ffd701SAndroid Build Coastguard Worker }
7993*35ffd701SAndroid Build Coastguard Worker #endif
7994*35ffd701SAndroid Build Coastguard Worker return crc;
7995*35ffd701SAndroid Build Coastguard Worker }
7996*35ffd701SAndroid Build Coastguard Worker
7997*35ffd701SAndroid Build Coastguard Worker /* AES */
7998*35ffd701SAndroid Build Coastguard Worker
7999*35ffd701SAndroid Build Coastguard Worker #if !defined(__ARM_FEATURE_CRYPTO)
8000*35ffd701SAndroid Build Coastguard Worker /* clang-format off */
8001*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_AES_DATA(w) \
8002*35ffd701SAndroid Build Coastguard Worker { \
8003*35ffd701SAndroid Build Coastguard Worker w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), \
8004*35ffd701SAndroid Build Coastguard Worker w(0xc5), w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), \
8005*35ffd701SAndroid Build Coastguard Worker w(0xab), w(0x76), w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), \
8006*35ffd701SAndroid Build Coastguard Worker w(0x59), w(0x47), w(0xf0), w(0xad), w(0xd4), w(0xa2), w(0xaf), \
8007*35ffd701SAndroid Build Coastguard Worker w(0x9c), w(0xa4), w(0x72), w(0xc0), w(0xb7), w(0xfd), w(0x93), \
8008*35ffd701SAndroid Build Coastguard Worker w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc), w(0x34), w(0xa5), \
8009*35ffd701SAndroid Build Coastguard Worker w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15), w(0x04), \
8010*35ffd701SAndroid Build Coastguard Worker w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a), \
8011*35ffd701SAndroid Build Coastguard Worker w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), \
8012*35ffd701SAndroid Build Coastguard Worker w(0x75), w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), \
8013*35ffd701SAndroid Build Coastguard Worker w(0x5a), w(0xa0), w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), \
8014*35ffd701SAndroid Build Coastguard Worker w(0xe3), w(0x2f), w(0x84), w(0x53), w(0xd1), w(0x00), w(0xed), \
8015*35ffd701SAndroid Build Coastguard Worker w(0x20), w(0xfc), w(0xb1), w(0x5b), w(0x6a), w(0xcb), w(0xbe), \
8016*35ffd701SAndroid Build Coastguard Worker w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf), w(0xd0), w(0xef), \
8017*35ffd701SAndroid Build Coastguard Worker w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85), w(0x45), \
8018*35ffd701SAndroid Build Coastguard Worker w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8), \
8019*35ffd701SAndroid Build Coastguard Worker w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), \
8020*35ffd701SAndroid Build Coastguard Worker w(0xf5), w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), \
8021*35ffd701SAndroid Build Coastguard Worker w(0xf3), w(0xd2), w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), \
8022*35ffd701SAndroid Build Coastguard Worker w(0x97), w(0x44), w(0x17), w(0xc4), w(0xa7), w(0x7e), w(0x3d), \
8023*35ffd701SAndroid Build Coastguard Worker w(0x64), w(0x5d), w(0x19), w(0x73), w(0x60), w(0x81), w(0x4f), \
8024*35ffd701SAndroid Build Coastguard Worker w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88), w(0x46), w(0xee), \
8025*35ffd701SAndroid Build Coastguard Worker w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb), w(0xe0), \
8026*35ffd701SAndroid Build Coastguard Worker w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c), \
8027*35ffd701SAndroid Build Coastguard Worker w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), \
8028*35ffd701SAndroid Build Coastguard Worker w(0x79), w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), \
8029*35ffd701SAndroid Build Coastguard Worker w(0x4e), w(0xa9), w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), \
8030*35ffd701SAndroid Build Coastguard Worker w(0x7a), w(0xae), w(0x08), w(0xba), w(0x78), w(0x25), w(0x2e), \
8031*35ffd701SAndroid Build Coastguard Worker w(0x1c), w(0xa6), w(0xb4), w(0xc6), w(0xe8), w(0xdd), w(0x74), \
8032*35ffd701SAndroid Build Coastguard Worker w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a), w(0x70), w(0x3e), \
8033*35ffd701SAndroid Build Coastguard Worker w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e), w(0x61), \
8034*35ffd701SAndroid Build Coastguard Worker w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e), \
8035*35ffd701SAndroid Build Coastguard Worker w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), \
8036*35ffd701SAndroid Build Coastguard Worker w(0x94), w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), \
8037*35ffd701SAndroid Build Coastguard Worker w(0x28), w(0xdf), w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), \
8038*35ffd701SAndroid Build Coastguard Worker w(0xe6), w(0x42), w(0x68), w(0x41), w(0x99), w(0x2d), w(0x0f), \
8039*35ffd701SAndroid Build Coastguard Worker w(0xb0), w(0x54), w(0xbb), w(0x16) \
8040*35ffd701SAndroid Build Coastguard Worker }
8041*35ffd701SAndroid Build Coastguard Worker /* clang-format on */
8042*35ffd701SAndroid Build Coastguard Worker
8043*35ffd701SAndroid Build Coastguard Worker /* X Macro trick. See https://en.wikipedia.org/wiki/X_Macro */
8044*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_AES_H0(x) (x)
8045*35ffd701SAndroid Build Coastguard Worker static const uint8_t SSE2NEON_sbox[256] = SSE2NEON_AES_DATA(SSE2NEON_AES_H0);
8046*35ffd701SAndroid Build Coastguard Worker #undef SSE2NEON_AES_H0
8047*35ffd701SAndroid Build Coastguard Worker
8048*35ffd701SAndroid Build Coastguard Worker // In the absence of crypto extensions, implement aesenc using regular neon
8049*35ffd701SAndroid Build Coastguard Worker // intrinsics instead. See:
8050*35ffd701SAndroid Build Coastguard Worker // https://www.workofard.com/2017/01/accelerated-aes-for-the-arm64-linux-kernel/
8051*35ffd701SAndroid Build Coastguard Worker // https://www.workofard.com/2017/07/ghash-for-low-end-cores/ and
8052*35ffd701SAndroid Build Coastguard Worker // https://github.com/ColinIanKing/linux-next-mirror/blob/b5f466091e130caaf0735976648f72bd5e09aa84/crypto/aegis128-neon-inner.c#L52
8053*35ffd701SAndroid Build Coastguard Worker // for more information Reproduced with permission of the author.
_mm_aesenc_si128(__m128i EncBlock,__m128i RoundKey)8054*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_aesenc_si128(__m128i EncBlock, __m128i RoundKey)
8055*35ffd701SAndroid Build Coastguard Worker {
8056*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
8057*35ffd701SAndroid Build Coastguard Worker static const uint8_t shift_rows[] = {0x0, 0x5, 0xa, 0xf, 0x4, 0x9,
8058*35ffd701SAndroid Build Coastguard Worker 0xe, 0x3, 0x8, 0xd, 0x2, 0x7,
8059*35ffd701SAndroid Build Coastguard Worker 0xc, 0x1, 0x6, 0xb};
8060*35ffd701SAndroid Build Coastguard Worker static const uint8_t ror32by8[] = {0x1, 0x2, 0x3, 0x0, 0x5, 0x6, 0x7, 0x4,
8061*35ffd701SAndroid Build Coastguard Worker 0x9, 0xa, 0xb, 0x8, 0xd, 0xe, 0xf, 0xc};
8062*35ffd701SAndroid Build Coastguard Worker
8063*35ffd701SAndroid Build Coastguard Worker uint8x16_t v;
8064*35ffd701SAndroid Build Coastguard Worker uint8x16_t w = vreinterpretq_u8_m128i(EncBlock);
8065*35ffd701SAndroid Build Coastguard Worker
8066*35ffd701SAndroid Build Coastguard Worker // shift rows
8067*35ffd701SAndroid Build Coastguard Worker w = vqtbl1q_u8(w, vld1q_u8(shift_rows));
8068*35ffd701SAndroid Build Coastguard Worker
8069*35ffd701SAndroid Build Coastguard Worker // sub bytes
8070*35ffd701SAndroid Build Coastguard Worker v = vqtbl4q_u8(_sse2neon_vld1q_u8_x4(SSE2NEON_sbox), w);
8071*35ffd701SAndroid Build Coastguard Worker v = vqtbx4q_u8(v, _sse2neon_vld1q_u8_x4(SSE2NEON_sbox + 0x40), w - 0x40);
8072*35ffd701SAndroid Build Coastguard Worker v = vqtbx4q_u8(v, _sse2neon_vld1q_u8_x4(SSE2NEON_sbox + 0x80), w - 0x80);
8073*35ffd701SAndroid Build Coastguard Worker v = vqtbx4q_u8(v, _sse2neon_vld1q_u8_x4(SSE2NEON_sbox + 0xc0), w - 0xc0);
8074*35ffd701SAndroid Build Coastguard Worker
8075*35ffd701SAndroid Build Coastguard Worker // mix columns
8076*35ffd701SAndroid Build Coastguard Worker w = (v << 1) ^ (uint8x16_t)(((int8x16_t) v >> 7) & 0x1b);
8077*35ffd701SAndroid Build Coastguard Worker w ^= (uint8x16_t) vrev32q_u16((uint16x8_t) v);
8078*35ffd701SAndroid Build Coastguard Worker w ^= vqtbl1q_u8(v ^ w, vld1q_u8(ror32by8));
8079*35ffd701SAndroid Build Coastguard Worker
8080*35ffd701SAndroid Build Coastguard Worker // add round key
8081*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(w) ^ RoundKey;
8082*35ffd701SAndroid Build Coastguard Worker
8083*35ffd701SAndroid Build Coastguard Worker #else /* ARMv7-A NEON implementation */
8084*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_AES_B2W(b0, b1, b2, b3) \
8085*35ffd701SAndroid Build Coastguard Worker (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | \
8086*35ffd701SAndroid Build Coastguard Worker (b0))
8087*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_AES_F2(x) ((x << 1) ^ (((x >> 7) & 1) * 0x011b /* WPOLY */))
8088*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_AES_F3(x) (SSE2NEON_AES_F2(x) ^ x)
8089*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_AES_U0(p) \
8090*35ffd701SAndroid Build Coastguard Worker SSE2NEON_AES_B2W(SSE2NEON_AES_F2(p), p, p, SSE2NEON_AES_F3(p))
8091*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_AES_U1(p) \
8092*35ffd701SAndroid Build Coastguard Worker SSE2NEON_AES_B2W(SSE2NEON_AES_F3(p), SSE2NEON_AES_F2(p), p, p)
8093*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_AES_U2(p) \
8094*35ffd701SAndroid Build Coastguard Worker SSE2NEON_AES_B2W(p, SSE2NEON_AES_F3(p), SSE2NEON_AES_F2(p), p)
8095*35ffd701SAndroid Build Coastguard Worker #define SSE2NEON_AES_U3(p) \
8096*35ffd701SAndroid Build Coastguard Worker SSE2NEON_AES_B2W(p, p, SSE2NEON_AES_F3(p), SSE2NEON_AES_F2(p))
8097*35ffd701SAndroid Build Coastguard Worker static const uint32_t ALIGN_STRUCT(16) aes_table[4][256] = {
8098*35ffd701SAndroid Build Coastguard Worker SSE2NEON_AES_DATA(SSE2NEON_AES_U0),
8099*35ffd701SAndroid Build Coastguard Worker SSE2NEON_AES_DATA(SSE2NEON_AES_U1),
8100*35ffd701SAndroid Build Coastguard Worker SSE2NEON_AES_DATA(SSE2NEON_AES_U2),
8101*35ffd701SAndroid Build Coastguard Worker SSE2NEON_AES_DATA(SSE2NEON_AES_U3),
8102*35ffd701SAndroid Build Coastguard Worker };
8103*35ffd701SAndroid Build Coastguard Worker #undef SSE2NEON_AES_B2W
8104*35ffd701SAndroid Build Coastguard Worker #undef SSE2NEON_AES_F2
8105*35ffd701SAndroid Build Coastguard Worker #undef SSE2NEON_AES_F3
8106*35ffd701SAndroid Build Coastguard Worker #undef SSE2NEON_AES_U0
8107*35ffd701SAndroid Build Coastguard Worker #undef SSE2NEON_AES_U1
8108*35ffd701SAndroid Build Coastguard Worker #undef SSE2NEON_AES_U2
8109*35ffd701SAndroid Build Coastguard Worker #undef SSE2NEON_AES_U3
8110*35ffd701SAndroid Build Coastguard Worker
8111*35ffd701SAndroid Build Coastguard Worker uint32_t x0 = _mm_cvtsi128_si32(EncBlock);
8112*35ffd701SAndroid Build Coastguard Worker uint32_t x1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(EncBlock, 0x55));
8113*35ffd701SAndroid Build Coastguard Worker uint32_t x2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(EncBlock, 0xAA));
8114*35ffd701SAndroid Build Coastguard Worker uint32_t x3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(EncBlock, 0xFF));
8115*35ffd701SAndroid Build Coastguard Worker
8116*35ffd701SAndroid Build Coastguard Worker __m128i out = _mm_set_epi32(
8117*35ffd701SAndroid Build Coastguard Worker (aes_table[0][x3 & 0xff] ^ aes_table[1][(x0 >> 8) & 0xff] ^
8118*35ffd701SAndroid Build Coastguard Worker aes_table[2][(x1 >> 16) & 0xff] ^ aes_table[3][x2 >> 24]),
8119*35ffd701SAndroid Build Coastguard Worker (aes_table[0][x2 & 0xff] ^ aes_table[1][(x3 >> 8) & 0xff] ^
8120*35ffd701SAndroid Build Coastguard Worker aes_table[2][(x0 >> 16) & 0xff] ^ aes_table[3][x1 >> 24]),
8121*35ffd701SAndroid Build Coastguard Worker (aes_table[0][x1 & 0xff] ^ aes_table[1][(x2 >> 8) & 0xff] ^
8122*35ffd701SAndroid Build Coastguard Worker aes_table[2][(x3 >> 16) & 0xff] ^ aes_table[3][x0 >> 24]),
8123*35ffd701SAndroid Build Coastguard Worker (aes_table[0][x0 & 0xff] ^ aes_table[1][(x1 >> 8) & 0xff] ^
8124*35ffd701SAndroid Build Coastguard Worker aes_table[2][(x2 >> 16) & 0xff] ^ aes_table[3][x3 >> 24]));
8125*35ffd701SAndroid Build Coastguard Worker
8126*35ffd701SAndroid Build Coastguard Worker return _mm_xor_si128(out, RoundKey);
8127*35ffd701SAndroid Build Coastguard Worker #endif
8128*35ffd701SAndroid Build Coastguard Worker }
8129*35ffd701SAndroid Build Coastguard Worker
8130*35ffd701SAndroid Build Coastguard Worker // Perform the last round of an AES encryption flow on data (state) in a using
8131*35ffd701SAndroid Build Coastguard Worker // the round key in RoundKey, and store the result in dst.
8132*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesenclast_si128
_mm_aesenclast_si128(__m128i a,__m128i RoundKey)8133*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_aesenclast_si128(__m128i a, __m128i RoundKey)
8134*35ffd701SAndroid Build Coastguard Worker {
8135*35ffd701SAndroid Build Coastguard Worker /* FIXME: optimized for NEON */
8136*35ffd701SAndroid Build Coastguard Worker uint8_t v[4][4] = {
8137*35ffd701SAndroid Build Coastguard Worker {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 0)],
8138*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 5)],
8139*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 10)],
8140*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 15)]},
8141*35ffd701SAndroid Build Coastguard Worker {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 4)],
8142*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 9)],
8143*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 14)],
8144*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 3)]},
8145*35ffd701SAndroid Build Coastguard Worker {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 8)],
8146*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 13)],
8147*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 2)],
8148*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 7)]},
8149*35ffd701SAndroid Build Coastguard Worker {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 12)],
8150*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 1)],
8151*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 6)],
8152*35ffd701SAndroid Build Coastguard Worker SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 11)]},
8153*35ffd701SAndroid Build Coastguard Worker };
8154*35ffd701SAndroid Build Coastguard Worker for (int i = 0; i < 16; i++)
8155*35ffd701SAndroid Build Coastguard Worker vreinterpretq_nth_u8_m128i(a, i) =
8156*35ffd701SAndroid Build Coastguard Worker v[i / 4][i % 4] ^ vreinterpretq_nth_u8_m128i(RoundKey, i);
8157*35ffd701SAndroid Build Coastguard Worker return a;
8158*35ffd701SAndroid Build Coastguard Worker }
8159*35ffd701SAndroid Build Coastguard Worker
8160*35ffd701SAndroid Build Coastguard Worker // Emits the Advanced Encryption Standard (AES) instruction aeskeygenassist.
8161*35ffd701SAndroid Build Coastguard Worker // This instruction generates a round key for AES encryption. See
8162*35ffd701SAndroid Build Coastguard Worker // https://kazakov.life/2017/11/01/cryptocurrency-mining-on-ios-devices/
8163*35ffd701SAndroid Build Coastguard Worker // for details.
8164*35ffd701SAndroid Build Coastguard Worker //
8165*35ffd701SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/cc714138(v=vs.120).aspx
_mm_aeskeygenassist_si128(__m128i key,const int rcon)8166*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i key, const int rcon)
8167*35ffd701SAndroid Build Coastguard Worker {
8168*35ffd701SAndroid Build Coastguard Worker uint32_t X1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0x55));
8169*35ffd701SAndroid Build Coastguard Worker uint32_t X3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(key, 0xFF));
8170*35ffd701SAndroid Build Coastguard Worker for (int i = 0; i < 4; ++i) {
8171*35ffd701SAndroid Build Coastguard Worker ((uint8_t *) &X1)[i] = SSE2NEON_sbox[((uint8_t *) &X1)[i]];
8172*35ffd701SAndroid Build Coastguard Worker ((uint8_t *) &X3)[i] = SSE2NEON_sbox[((uint8_t *) &X3)[i]];
8173*35ffd701SAndroid Build Coastguard Worker }
8174*35ffd701SAndroid Build Coastguard Worker return _mm_set_epi32(((X3 >> 8) | (X3 << 24)) ^ rcon, X3,
8175*35ffd701SAndroid Build Coastguard Worker ((X1 >> 8) | (X1 << 24)) ^ rcon, X1);
8176*35ffd701SAndroid Build Coastguard Worker }
8177*35ffd701SAndroid Build Coastguard Worker #undef SSE2NEON_AES_DATA
8178*35ffd701SAndroid Build Coastguard Worker
8179*35ffd701SAndroid Build Coastguard Worker #else /* __ARM_FEATURE_CRYPTO */
8180*35ffd701SAndroid Build Coastguard Worker // Implements equivalent of 'aesenc' by combining AESE (with an empty key) and
8181*35ffd701SAndroid Build Coastguard Worker // AESMC and then manually applying the real key as an xor operation. This
8182*35ffd701SAndroid Build Coastguard Worker // unfortunately means an additional xor op; the compiler should be able to
8183*35ffd701SAndroid Build Coastguard Worker // optimize this away for repeated calls however. See
8184*35ffd701SAndroid Build Coastguard Worker // https://blog.michaelbrase.com/2018/05/08/emulating-x86-aes-intrinsics-on-armv8-a
8185*35ffd701SAndroid Build Coastguard Worker // for more details.
_mm_aesenc_si128(__m128i a,__m128i b)8186*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_aesenc_si128(__m128i a, __m128i b)
8187*35ffd701SAndroid Build Coastguard Worker {
8188*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(
8189*35ffd701SAndroid Build Coastguard Worker vaesmcq_u8(vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0))) ^
8190*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_m128i(b));
8191*35ffd701SAndroid Build Coastguard Worker }
8192*35ffd701SAndroid Build Coastguard Worker
8193*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_aesenclast_si128
_mm_aesenclast_si128(__m128i a,__m128i RoundKey)8194*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_aesenclast_si128(__m128i a, __m128i RoundKey)
8195*35ffd701SAndroid Build Coastguard Worker {
8196*35ffd701SAndroid Build Coastguard Worker return _mm_xor_si128(vreinterpretq_m128i_u8(vaeseq_u8(
8197*35ffd701SAndroid Build Coastguard Worker vreinterpretq_u8_m128i(a), vdupq_n_u8(0))),
8198*35ffd701SAndroid Build Coastguard Worker RoundKey);
8199*35ffd701SAndroid Build Coastguard Worker }
8200*35ffd701SAndroid Build Coastguard Worker
_mm_aeskeygenassist_si128(__m128i a,const int rcon)8201*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i a, const int rcon)
8202*35ffd701SAndroid Build Coastguard Worker {
8203*35ffd701SAndroid Build Coastguard Worker // AESE does ShiftRows and SubBytes on A
8204*35ffd701SAndroid Build Coastguard Worker uint8x16_t u8 = vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0));
8205*35ffd701SAndroid Build Coastguard Worker
8206*35ffd701SAndroid Build Coastguard Worker uint8x16_t dest = {
8207*35ffd701SAndroid Build Coastguard Worker // Undo ShiftRows step from AESE and extract X1 and X3
8208*35ffd701SAndroid Build Coastguard Worker u8[0x4], u8[0x1], u8[0xE], u8[0xB], // SubBytes(X1)
8209*35ffd701SAndroid Build Coastguard Worker u8[0x1], u8[0xE], u8[0xB], u8[0x4], // ROT(SubBytes(X1))
8210*35ffd701SAndroid Build Coastguard Worker u8[0xC], u8[0x9], u8[0x6], u8[0x3], // SubBytes(X3)
8211*35ffd701SAndroid Build Coastguard Worker u8[0x9], u8[0x6], u8[0x3], u8[0xC], // ROT(SubBytes(X3))
8212*35ffd701SAndroid Build Coastguard Worker };
8213*35ffd701SAndroid Build Coastguard Worker uint32x4_t r = {0, (unsigned) rcon, 0, (unsigned) rcon};
8214*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u8(dest) ^ vreinterpretq_m128i_u32(r);
8215*35ffd701SAndroid Build Coastguard Worker }
8216*35ffd701SAndroid Build Coastguard Worker #endif
8217*35ffd701SAndroid Build Coastguard Worker
8218*35ffd701SAndroid Build Coastguard Worker /* Others */
8219*35ffd701SAndroid Build Coastguard Worker
8220*35ffd701SAndroid Build Coastguard Worker // Perform a carry-less multiplication of two 64-bit integers, selected from a
8221*35ffd701SAndroid Build Coastguard Worker // and b according to imm8, and store the results in dst.
8222*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_clmulepi64_si128
_mm_clmulepi64_si128(__m128i _a,__m128i _b,const int imm)8223*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE __m128i _mm_clmulepi64_si128(__m128i _a, __m128i _b, const int imm)
8224*35ffd701SAndroid Build Coastguard Worker {
8225*35ffd701SAndroid Build Coastguard Worker uint64x2_t a = vreinterpretq_u64_m128i(_a);
8226*35ffd701SAndroid Build Coastguard Worker uint64x2_t b = vreinterpretq_u64_m128i(_b);
8227*35ffd701SAndroid Build Coastguard Worker switch (imm & 0x11) {
8228*35ffd701SAndroid Build Coastguard Worker case 0x00:
8229*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(
8230*35ffd701SAndroid Build Coastguard Worker _sse2neon_vmull_p64(vget_low_u64(a), vget_low_u64(b)));
8231*35ffd701SAndroid Build Coastguard Worker case 0x01:
8232*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(
8233*35ffd701SAndroid Build Coastguard Worker _sse2neon_vmull_p64(vget_high_u64(a), vget_low_u64(b)));
8234*35ffd701SAndroid Build Coastguard Worker case 0x10:
8235*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(
8236*35ffd701SAndroid Build Coastguard Worker _sse2neon_vmull_p64(vget_low_u64(a), vget_high_u64(b)));
8237*35ffd701SAndroid Build Coastguard Worker case 0x11:
8238*35ffd701SAndroid Build Coastguard Worker return vreinterpretq_m128i_u64(
8239*35ffd701SAndroid Build Coastguard Worker _sse2neon_vmull_p64(vget_high_u64(a), vget_high_u64(b)));
8240*35ffd701SAndroid Build Coastguard Worker default:
8241*35ffd701SAndroid Build Coastguard Worker abort();
8242*35ffd701SAndroid Build Coastguard Worker }
8243*35ffd701SAndroid Build Coastguard Worker }
8244*35ffd701SAndroid Build Coastguard Worker
8245*35ffd701SAndroid Build Coastguard Worker // Count the number of bits set to 1 in unsigned 32-bit integer a, and
8246*35ffd701SAndroid Build Coastguard Worker // return that count in dst.
8247*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u32
_mm_popcnt_u32(unsigned int a)8248*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int _mm_popcnt_u32(unsigned int a)
8249*35ffd701SAndroid Build Coastguard Worker {
8250*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
8251*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_popcount)
8252*35ffd701SAndroid Build Coastguard Worker return __builtin_popcount(a);
8253*35ffd701SAndroid Build Coastguard Worker #else
8254*35ffd701SAndroid Build Coastguard Worker return (int) vaddlv_u8(vcnt_u8(vcreate_u8((uint64_t) a)));
8255*35ffd701SAndroid Build Coastguard Worker #endif
8256*35ffd701SAndroid Build Coastguard Worker #else
8257*35ffd701SAndroid Build Coastguard Worker uint32_t count = 0;
8258*35ffd701SAndroid Build Coastguard Worker uint8x8_t input_val, count8x8_val;
8259*35ffd701SAndroid Build Coastguard Worker uint16x4_t count16x4_val;
8260*35ffd701SAndroid Build Coastguard Worker uint32x2_t count32x2_val;
8261*35ffd701SAndroid Build Coastguard Worker
8262*35ffd701SAndroid Build Coastguard Worker input_val = vld1_u8((uint8_t *) &a);
8263*35ffd701SAndroid Build Coastguard Worker count8x8_val = vcnt_u8(input_val);
8264*35ffd701SAndroid Build Coastguard Worker count16x4_val = vpaddl_u8(count8x8_val);
8265*35ffd701SAndroid Build Coastguard Worker count32x2_val = vpaddl_u16(count16x4_val);
8266*35ffd701SAndroid Build Coastguard Worker
8267*35ffd701SAndroid Build Coastguard Worker vst1_u32(&count, count32x2_val);
8268*35ffd701SAndroid Build Coastguard Worker return count;
8269*35ffd701SAndroid Build Coastguard Worker #endif
8270*35ffd701SAndroid Build Coastguard Worker }
8271*35ffd701SAndroid Build Coastguard Worker
8272*35ffd701SAndroid Build Coastguard Worker // Count the number of bits set to 1 in unsigned 64-bit integer a, and
8273*35ffd701SAndroid Build Coastguard Worker // return that count in dst.
8274*35ffd701SAndroid Build Coastguard Worker // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u64
_mm_popcnt_u64(uint64_t a)8275*35ffd701SAndroid Build Coastguard Worker FORCE_INLINE int64_t _mm_popcnt_u64(uint64_t a)
8276*35ffd701SAndroid Build Coastguard Worker {
8277*35ffd701SAndroid Build Coastguard Worker #if defined(__aarch64__)
8278*35ffd701SAndroid Build Coastguard Worker #if __has_builtin(__builtin_popcountll)
8279*35ffd701SAndroid Build Coastguard Worker return __builtin_popcountll(a);
8280*35ffd701SAndroid Build Coastguard Worker #else
8281*35ffd701SAndroid Build Coastguard Worker return (int64_t) vaddlv_u8(vcnt_u8(vcreate_u8(a)));
8282*35ffd701SAndroid Build Coastguard Worker #endif
8283*35ffd701SAndroid Build Coastguard Worker #else
8284*35ffd701SAndroid Build Coastguard Worker uint64_t count = 0;
8285*35ffd701SAndroid Build Coastguard Worker uint8x8_t input_val, count8x8_val;
8286*35ffd701SAndroid Build Coastguard Worker uint16x4_t count16x4_val;
8287*35ffd701SAndroid Build Coastguard Worker uint32x2_t count32x2_val;
8288*35ffd701SAndroid Build Coastguard Worker uint64x1_t count64x1_val;
8289*35ffd701SAndroid Build Coastguard Worker
8290*35ffd701SAndroid Build Coastguard Worker input_val = vld1_u8((uint8_t *) &a);
8291*35ffd701SAndroid Build Coastguard Worker count8x8_val = vcnt_u8(input_val);
8292*35ffd701SAndroid Build Coastguard Worker count16x4_val = vpaddl_u8(count8x8_val);
8293*35ffd701SAndroid Build Coastguard Worker count32x2_val = vpaddl_u16(count16x4_val);
8294*35ffd701SAndroid Build Coastguard Worker count64x1_val = vpaddl_u32(count32x2_val);
8295*35ffd701SAndroid Build Coastguard Worker vst1_u64(&count, count64x1_val);
8296*35ffd701SAndroid Build Coastguard Worker return count;
8297*35ffd701SAndroid Build Coastguard Worker #endif
8298*35ffd701SAndroid Build Coastguard Worker }
8299*35ffd701SAndroid Build Coastguard Worker
8300*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
8301*35ffd701SAndroid Build Coastguard Worker #pragma pop_macro("ALIGN_STRUCT")
8302*35ffd701SAndroid Build Coastguard Worker #pragma pop_macro("FORCE_INLINE")
8303*35ffd701SAndroid Build Coastguard Worker #endif
8304*35ffd701SAndroid Build Coastguard Worker
8305*35ffd701SAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__clang__)
8306*35ffd701SAndroid Build Coastguard Worker #pragma GCC pop_options
8307*35ffd701SAndroid Build Coastguard Worker #endif
8308*35ffd701SAndroid Build Coastguard Worker
8309*35ffd701SAndroid Build Coastguard Worker #endif
8310*35ffd701SAndroid Build Coastguard Worker
8311