smmintrin.h revision 360784
1/*===---- smmintrin.h - Implementation of SSE4 intrinsics on PowerPC -------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 *===-----------------------------------------------------------------------===
8 */
9
10/* Implemented from the specification included in the Intel C++ Compiler
11   User Guide and Reference, version 9.0.
12
13   NOTE: This is NOT a complete implementation of the SSE4 intrinsics!  */
14
15#ifndef NO_WARN_X86_INTRINSICS
16/* This header is distributed to simplify porting x86_64 code that
17   makes explicit use of Intel intrinsics to powerp64/powerpc64le.
18
19   It is the user's responsibility to determine if the results are
20   acceptable and make additional changes as necessary.
21
22   Note that much code that uses Intel intrinsics can be rewritten in
23   standard C or GNU C extensions, which are more portable and better
24   optimized across multiple targets.  */
25#error                                                                         \
26    "Please read comment above.  Use -DNO_WARN_X86_INTRINSICS to disable this error."
27#endif
28
29#ifndef SMMINTRIN_H_
30#define SMMINTRIN_H_
31
32#if defined(__linux__) && defined(__ppc64__)
33
34#include <altivec.h>
35#include <emmintrin.h>
36
37extern __inline int
38    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
39    _mm_extract_epi8(__m128i __X, const int __N) {
40  return (unsigned char)((__v16qi)__X)[__N & 15];
41}
42
43extern __inline int
44    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
45    _mm_extract_epi32(__m128i __X, const int __N) {
46  return ((__v4si)__X)[__N & 3];
47}
48
49extern __inline int
50    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
51    _mm_extract_epi64(__m128i __X, const int __N) {
52  return ((__v2di)__X)[__N & 1];
53}
54
55extern __inline int
56    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
57    _mm_extract_ps(__m128 __X, const int __N) {
58  return ((__v4si)__X)[__N & 3];
59}
60
61extern __inline __m128i
62    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
63    _mm_blend_epi16(__m128i __A, __m128i __B, const int __imm8) {
64  __v16qi __charmask = vec_splats((signed char)__imm8);
65  __charmask = vec_gb(__charmask);
66  __v8hu __shortmask = (__v8hu)vec_unpackh(__charmask);
67#ifdef __BIG_ENDIAN__
68  __shortmask = vec_reve(__shortmask);
69#endif
70  return (__m128i)vec_sel((__v8hu)__A, (__v8hu)__B, __shortmask);
71}
72
73extern __inline __m128i
74    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
75    _mm_blendv_epi8(__m128i __A, __m128i __B, __m128i __mask) {
76  const __v16qu __seven = vec_splats((unsigned char)0x07);
77  __v16qu __lmask = vec_sra((__v16qu)__mask, __seven);
78  return (__m128i)vec_sel((__v16qu)__A, (__v16qu)__B, __lmask);
79}
80
81#else
82#include_next <smmintrin.h>
83#endif /* defined(__linux__) && defined(__ppc64__) */
84
85#endif /* _SMMINTRIN_H_ */
86