Home | History | Annotate | Download | only in include
      1 /* Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
      2 
      3    This file is part of GCC.
      4 
      5    GCC is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation; either version 3, or (at your option)
      8    any later version.
      9 
     10    GCC is distributed in the hope that it will be useful,
     11    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13    GNU General Public License for more details.
     14 
     15    Under Section 7 of GPL version 3, you are granted additional
     16    permissions described in the GCC Runtime Library Exception, version
     17    3.1, as published by the Free Software Foundation.
     18 
     19    You should have received a copy of the GNU General Public License and
     20    a copy of the GCC Runtime Library Exception along with this program;
     21    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     22    <http://www.gnu.org/licenses/>.
     23 
     24 
     25 /* Implemented from the specification included in the Intel C++ Compiler
     26    User Guide and Reference, version 10.0.  */
     27 
     28 #ifndef _SMMINTRIN_H_INCLUDED
     29 #define _SMMINTRIN_H_INCLUDED
     30 
     31 #ifndef __SSE4_1__
     32 # error "SSE4.1 instruction set not enabled"
     33 #else
     34 
     35 /* We need definitions from the SSSE3, SSE3, SSE2 and SSE header
     36    files.  */
     37 #include <tmmintrin.h>
     38 #include <mmintrin-common.h>
     39 
     40 /* SSE4.1 */
     41 
     42 /* Integer blend instructions - select data from 2 sources using
     43    constant/variable mask.  */
     44 
     45 #ifdef __OPTIMIZE__
     46 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
     47 _mm_blend_epi16 (__m128i __X, __m128i __Y, const int __M)
     48 {
     49   return (__m128i) __builtin_ia32_pblendw128 ((__v8hi)__X,
     50 					      (__v8hi)__Y,
     51 					      __M);
     52 }
     53 #else
     54 #define _mm_blend_epi16(X, Y, M)					\
     55   ((__m128i) __builtin_ia32_pblendw128 ((__v8hi)(__m128i)(X),		\
     56 					(__v8hi)(__m128i)(Y), (int)(M)))
     57 #endif
     58 
     59 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
     60 _mm_blendv_epi8 (__m128i __X, __m128i __Y, __m128i __M)
     61 {
     62   return (__m128i) __builtin_ia32_pblendvb128 ((__v16qi)__X,
     63 					       (__v16qi)__Y,
     64 					       (__v16qi)__M);
     65 }
     66 
     67 /* Single precision floating point blend instructions - select data
     68    from 2 sources using constant/variable mask.  */
     69 
     70 #ifdef __OPTIMIZE__
     71 extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
     72 _mm_blend_ps (__m128 __X, __m128 __Y, const int __M)
     73 {
     74   return (__m128) __builtin_ia32_blendps ((__v4sf)__X,
     75 					  (__v4sf)__Y,
     76 					  __M);
     77 }
     78 #else
     79 #define _mm_blend_ps(X, Y, M)						\
     80   ((__m128) __builtin_ia32_blendps ((__v4sf)(__m128)(X),		\
     81 				    (__v4sf)(__m128)(Y), (int)(M)))
     82 #endif
     83 
     84 extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
     85 _mm_blendv_ps (__m128 __X, __m128 __Y, __m128 __M)
     86 {
     87   return (__m128) __builtin_ia32_blendvps ((__v4sf)__X,
     88 					   (__v4sf)__Y,
     89 					   (__v4sf)__M);
     90 }
     91 
     92 /* Double precision floating point blend instructions - select data
     93    from 2 sources using constant/variable mask.  */
     94 
     95 #ifdef __OPTIMIZE__
     96 extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__))
     97 _mm_blend_pd (__m128d __X, __m128d __Y, const int __M)
     98 {
     99   return (__m128d) __builtin_ia32_blendpd ((__v2df)__X,
    100 					   (__v2df)__Y,
    101 					   __M);
    102 }
    103 #else
    104 #define _mm_blend_pd(X, Y, M)						\
    105   ((__m128d) __builtin_ia32_blendpd ((__v2df)(__m128d)(X),		\
    106 				     (__v2df)(__m128d)(Y), (int)(M)))
    107 #endif
    108 
    109 extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    110 _mm_blendv_pd (__m128d __X, __m128d __Y, __m128d __M)
    111 {
    112   return (__m128d) __builtin_ia32_blendvpd ((__v2df)__X,
    113 					    (__v2df)__Y,
    114 					    (__v2df)__M);
    115 }
    116 
    117 /* Dot product instructions with mask-defined summing and zeroing parts
    118    of result.  */
    119 
    120 #ifdef __OPTIMIZE__
    121 extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    122 _mm_dp_ps (__m128 __X, __m128 __Y, const int __M)
    123 {
    124   return (__m128) __builtin_ia32_dpps ((__v4sf)__X,
    125 				       (__v4sf)__Y,
    126 				       __M);
    127 }
    128 
    129 extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    130 _mm_dp_pd (__m128d __X, __m128d __Y, const int __M)
    131 {
    132   return (__m128d) __builtin_ia32_dppd ((__v2df)__X,
    133 					(__v2df)__Y,
    134 					__M);
    135 }
    136 #else
    137 #define _mm_dp_ps(X, Y, M)						\
    138   ((__m128) __builtin_ia32_dpps ((__v4sf)(__m128)(X),			\
    139 				 (__v4sf)(__m128)(Y), (int)(M)))
    140 
    141 #define _mm_dp_pd(X, Y, M)						\
    142   ((__m128d) __builtin_ia32_dppd ((__v2df)(__m128d)(X),			\
    143 				  (__v2df)(__m128d)(Y), (int)(M)))
    144 #endif
    145 
    146 /* Packed integer 64-bit comparison, zeroing or filling with ones
    147    corresponding parts of result.  */
    148 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    149 _mm_cmpeq_epi64 (__m128i __X, __m128i __Y)
    150 {
    151   return (__m128i) __builtin_ia32_pcmpeqq ((__v2di)__X, (__v2di)__Y);
    152 }
    153 
    154 /*  Min/max packed integer instructions.  */
    155 
    156 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    157 _mm_min_epi8 (__m128i __X, __m128i __Y)
    158 {
    159   return (__m128i) __builtin_ia32_pminsb128 ((__v16qi)__X, (__v16qi)__Y);
    160 }
    161 
    162 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    163 _mm_max_epi8 (__m128i __X, __m128i __Y)
    164 {
    165   return (__m128i) __builtin_ia32_pmaxsb128 ((__v16qi)__X, (__v16qi)__Y);
    166 }
    167 
    168 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    169 _mm_min_epu16 (__m128i __X, __m128i __Y)
    170 {
    171   return (__m128i) __builtin_ia32_pminuw128 ((__v8hi)__X, (__v8hi)__Y);
    172 }
    173 
    174 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    175 _mm_max_epu16 (__m128i __X, __m128i __Y)
    176 {
    177   return (__m128i) __builtin_ia32_pmaxuw128 ((__v8hi)__X, (__v8hi)__Y);
    178 }
    179 
    180 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    181 _mm_min_epi32 (__m128i __X, __m128i __Y)
    182 {
    183   return (__m128i) __builtin_ia32_pminsd128 ((__v4si)__X, (__v4si)__Y);
    184 }
    185 
    186 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    187 _mm_max_epi32 (__m128i __X, __m128i __Y)
    188 {
    189   return (__m128i) __builtin_ia32_pmaxsd128 ((__v4si)__X, (__v4si)__Y);
    190 }
    191 
    192 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    193 _mm_min_epu32 (__m128i __X, __m128i __Y)
    194 {
    195   return (__m128i) __builtin_ia32_pminud128 ((__v4si)__X, (__v4si)__Y);
    196 }
    197 
    198 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    199 _mm_max_epu32 (__m128i __X, __m128i __Y)
    200 {
    201   return (__m128i) __builtin_ia32_pmaxud128 ((__v4si)__X, (__v4si)__Y);
    202 }
    203 
    204 /* Packed integer 32-bit multiplication with truncation of upper
    205    halves of results.  */
    206 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    207 _mm_mullo_epi32 (__m128i __X, __m128i __Y)
    208 {
    209   return (__m128i) __builtin_ia32_pmulld128 ((__v4si)__X, (__v4si)__Y);
    210 }
    211 
    212 /* Packed integer 32-bit multiplication of 2 pairs of operands
    213    with two 64-bit results.  */
    214 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    215 _mm_mul_epi32 (__m128i __X, __m128i __Y)
    216 {
    217   return (__m128i) __builtin_ia32_pmuldq128 ((__v4si)__X, (__v4si)__Y);
    218 }
    219 
    220 /* Insert single precision float into packed single precision array
    221    element selected by index N.  The bits [7-6] of N define S
    222    index, the bits [5-4] define D index, and bits [3-0] define
    223    zeroing mask for D.  */
    224 
    225 #ifdef __OPTIMIZE__
    226 extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    227 _mm_insert_ps (__m128 __D, __m128 __S, const int __N)
    228 {
    229   return (__m128) __builtin_ia32_insertps128 ((__v4sf)__D,
    230 					      (__v4sf)__S,
    231 					      __N);
    232 }
    233 #else
    234 #define _mm_insert_ps(D, S, N)						\
    235   ((__m128) __builtin_ia32_insertps128 ((__v4sf)(__m128)(D),		\
    236 					(__v4sf)(__m128)(S), (int)(N)))
    237 #endif
    238 
    239 /* Helper macro to create the N value for _mm_insert_ps.  */
    240 #define _MM_MK_INSERTPS_NDX(S, D, M) (((S) << 6) | ((D) << 4) | (M))
    241 
    242 /* Extract binary representation of single precision float from packed
    243    single precision array element of X selected by index N.  */
    244 
    245 #ifdef __OPTIMIZE__
    246 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    247 _mm_extract_ps (__m128 __X, const int __N)
    248 {
    249   union { int i; float f; } __tmp;
    250   __tmp.f = __builtin_ia32_vec_ext_v4sf ((__v4sf)__X, __N);
    251   return __tmp.i;
    252 }
    253 #else
    254 #define _mm_extract_ps(X, N)						\
    255   (__extension__							\
    256    ({									\
    257      union { int i; float f; } __tmp;					\
    258      __tmp.f = __builtin_ia32_vec_ext_v4sf ((__v4sf)(__m128)(X), (int)(N)); \
    259      __tmp.i;								\
    260    }))
    261 #endif
    262 
    263 /* Extract binary representation of single precision float into
    264    D from packed single precision array element of S selected
    265    by index N.  */
    266 #define _MM_EXTRACT_FLOAT(D, S, N) \
    267   { (D) = __builtin_ia32_vec_ext_v4sf ((__v4sf)(S), (N)); }
    268 
    269 /* Extract specified single precision float element into the lower
    270    part of __m128.  */
    271 #define _MM_PICK_OUT_PS(X, N)				\
    272   _mm_insert_ps (_mm_setzero_ps (), (X), 		\
    273 		 _MM_MK_INSERTPS_NDX ((N), 0, 0x0e))
    274 
    275 /* Insert integer, S, into packed integer array element of D
    276    selected by index N.  */
    277 
    278 #ifdef __OPTIMIZE__
    279 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    280 _mm_insert_epi8 (__m128i __D, int __S, const int __N)
    281 {
    282   return (__m128i) __builtin_ia32_vec_set_v16qi ((__v16qi)__D,
    283 						 __S, __N);
    284 }
    285 
    286 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    287 _mm_insert_epi32 (__m128i __D, int __S, const int __N)
    288 {
    289   return (__m128i) __builtin_ia32_vec_set_v4si ((__v4si)__D,
    290 						 __S, __N);
    291 }
    292 
    293 #ifdef __x86_64__
    294 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    295 _mm_insert_epi64 (__m128i __D, long long __S, const int __N)
    296 {
    297   return (__m128i) __builtin_ia32_vec_set_v2di ((__v2di)__D,
    298 						 __S, __N);
    299 }
    300 #endif
    301 #else
    302 #define _mm_insert_epi8(D, S, N)					\
    303   ((__m128i) __builtin_ia32_vec_set_v16qi ((__v16qi)(__m128i)(D),	\
    304 					   (int)(S), (int)(N)))
    305 
    306 #define _mm_insert_epi32(D, S, N)				\
    307   ((__m128i) __builtin_ia32_vec_set_v4si ((__v4si)(__m128i)(D),	\
    308 					  (int)(S), (int)(N)))
    309 
    310 #ifdef __x86_64__
    311 #define _mm_insert_epi64(D, S, N)					\
    312   ((__m128i) __builtin_ia32_vec_set_v2di ((__v2di)(__m128i)(D),		\
    313 					  (long long)(S), (int)(N)))
    314 #endif
    315 #endif
    316 
    317 /* Extract integer from packed integer array element of X selected by
    318    index N.  */
    319 
    320 #ifdef __OPTIMIZE__
    321 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    322 _mm_extract_epi8 (__m128i __X, const int __N)
    323 {
    324    return __builtin_ia32_vec_ext_v16qi ((__v16qi)__X, __N);
    325 }
    326 
    327 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    328 _mm_extract_epi32 (__m128i __X, const int __N)
    329 {
    330    return __builtin_ia32_vec_ext_v4si ((__v4si)__X, __N);
    331 }
    332 
    333 #ifdef __x86_64__
    334 extern __inline long long  __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    335 _mm_extract_epi64 (__m128i __X, const int __N)
    336 {
    337   return __builtin_ia32_vec_ext_v2di ((__v2di)__X, __N);
    338 }
    339 #endif
    340 #else
    341 #define _mm_extract_epi8(X, N) \
    342   ((int) __builtin_ia32_vec_ext_v16qi ((__v16qi)(__m128i)(X), (int)(N)))
    343 #define _mm_extract_epi32(X, N) \
    344   ((int) __builtin_ia32_vec_ext_v4si ((__v4si)(__m128i)(X), (int)(N)))
    345 
    346 #ifdef __x86_64__
    347 #define _mm_extract_epi64(X, N) \
    348   ((long long) __builtin_ia32_vec_ext_v2di ((__v2di)(__m128i)(X), (int)(N)))
    349 #endif
    350 #endif
    351 
    352 /* Return horizontal packed word minimum and its index in bits [15:0]
    353    and bits [18:16] respectively.  */
    354 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    355 _mm_minpos_epu16 (__m128i __X)
    356 {
    357   return (__m128i) __builtin_ia32_phminposuw128 ((__v8hi)__X);
    358 }
    359 
    360 /* Packed integer sign-extension.  */
    361 
    362 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    363 _mm_cvtepi8_epi32 (__m128i __X)
    364 {
    365   return (__m128i) __builtin_ia32_pmovsxbd128 ((__v16qi)__X);
    366 }
    367 
    368 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    369 _mm_cvtepi16_epi32 (__m128i __X)
    370 {
    371   return (__m128i) __builtin_ia32_pmovsxwd128 ((__v8hi)__X);
    372 }
    373 
    374 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    375 _mm_cvtepi8_epi64 (__m128i __X)
    376 {
    377   return (__m128i) __builtin_ia32_pmovsxbq128 ((__v16qi)__X);
    378 }
    379 
    380 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    381 _mm_cvtepi32_epi64 (__m128i __X)
    382 {
    383   return (__m128i) __builtin_ia32_pmovsxdq128 ((__v4si)__X);
    384 }
    385 
    386 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    387 _mm_cvtepi16_epi64 (__m128i __X)
    388 {
    389   return (__m128i) __builtin_ia32_pmovsxwq128 ((__v8hi)__X);
    390 }
    391 
    392 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    393 _mm_cvtepi8_epi16 (__m128i __X)
    394 {
    395   return (__m128i) __builtin_ia32_pmovsxbw128 ((__v16qi)__X);
    396 }
    397 
    398 /* Packed integer zero-extension. */
    399 
    400 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    401 _mm_cvtepu8_epi32 (__m128i __X)
    402 {
    403   return (__m128i) __builtin_ia32_pmovzxbd128 ((__v16qi)__X);
    404 }
    405 
    406 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    407 _mm_cvtepu16_epi32 (__m128i __X)
    408 {
    409   return (__m128i) __builtin_ia32_pmovzxwd128 ((__v8hi)__X);
    410 }
    411 
    412 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    413 _mm_cvtepu8_epi64 (__m128i __X)
    414 {
    415   return (__m128i) __builtin_ia32_pmovzxbq128 ((__v16qi)__X);
    416 }
    417 
    418 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    419 _mm_cvtepu32_epi64 (__m128i __X)
    420 {
    421   return (__m128i) __builtin_ia32_pmovzxdq128 ((__v4si)__X);
    422 }
    423 
    424 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    425 _mm_cvtepu16_epi64 (__m128i __X)
    426 {
    427   return (__m128i) __builtin_ia32_pmovzxwq128 ((__v8hi)__X);
    428 }
    429 
    430 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    431 _mm_cvtepu8_epi16 (__m128i __X)
    432 {
    433   return (__m128i) __builtin_ia32_pmovzxbw128 ((__v16qi)__X);
    434 }
    435 
    436 /* Pack 8 double words from 2 operands into 8 words of result with
    437    unsigned saturation. */
    438 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    439 _mm_packus_epi32 (__m128i __X, __m128i __Y)
    440 {
    441   return (__m128i) __builtin_ia32_packusdw128 ((__v4si)__X, (__v4si)__Y);
    442 }
    443 
    444 /* Sum absolute 8-bit integer difference of adjacent groups of 4
    445    byte integers in the first 2 operands.  Starting offsets within
    446    operands are determined by the 3rd mask operand.  */
    447 
    448 #ifdef __OPTIMIZE__
    449 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    450 _mm_mpsadbw_epu8 (__m128i __X, __m128i __Y, const int __M)
    451 {
    452   return (__m128i) __builtin_ia32_mpsadbw128 ((__v16qi)__X,
    453 					      (__v16qi)__Y, __M);
    454 }
    455 #else
    456 #define _mm_mpsadbw_epu8(X, Y, M)					\
    457   ((__m128i) __builtin_ia32_mpsadbw128 ((__v16qi)(__m128i)(X),		\
    458 					(__v16qi)(__m128i)(Y), (int)(M)))
    459 #endif
    460 
    461 /* Load double quadword using non-temporal aligned hint.  */
    462 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    463 _mm_stream_load_si128 (__m128i *__X)
    464 {
    465   return (__m128i) __builtin_ia32_movntdqa ((__v2di *) __X);
    466 }
    467 
    468 #ifdef __SSE4_2__
    469 
    470 /* These macros specify the source data format.  */
    471 #define _SIDD_UBYTE_OPS			0x00
    472 #define _SIDD_UWORD_OPS			0x01
    473 #define _SIDD_SBYTE_OPS			0x02
    474 #define _SIDD_SWORD_OPS			0x03
    475 
    476 /* These macros specify the comparison operation.  */
    477 #define _SIDD_CMP_EQUAL_ANY		0x00
    478 #define _SIDD_CMP_RANGES		0x04
    479 #define _SIDD_CMP_EQUAL_EACH		0x08
    480 #define _SIDD_CMP_EQUAL_ORDERED		0x0c
    481 
    482 /* These macros specify the the polarity.  */
    483 #define _SIDD_POSITIVE_POLARITY		0x00
    484 #define _SIDD_NEGATIVE_POLARITY		0x10
    485 #define _SIDD_MASKED_POSITIVE_POLARITY	0x20
    486 #define _SIDD_MASKED_NEGATIVE_POLARITY	0x30
    487 
    488 /* These macros specify the output selection in _mm_cmpXstri ().  */
    489 #define _SIDD_LEAST_SIGNIFICANT		0x00
    490 #define _SIDD_MOST_SIGNIFICANT		0x40
    491 
    492 /* These macros specify the output selection in _mm_cmpXstrm ().  */
    493 #define _SIDD_BIT_MASK			0x00
    494 #define _SIDD_UNIT_MASK			0x40
    495 
    496 /* Intrinsics for text/string processing.  */
    497 
    498 #ifdef __OPTIMIZE__
    499 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    500 _mm_cmpistrm (__m128i __X, __m128i __Y, const int __M)
    501 {
    502   return (__m128i) __builtin_ia32_pcmpistrm128 ((__v16qi)__X,
    503 						(__v16qi)__Y,
    504 						__M);
    505 }
    506 
    507 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    508 _mm_cmpistri (__m128i __X, __m128i __Y, const int __M)
    509 {
    510   return __builtin_ia32_pcmpistri128 ((__v16qi)__X,
    511 				      (__v16qi)__Y,
    512 				      __M);
    513 }
    514 
    515 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    516 _mm_cmpestrm (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M)
    517 {
    518   return (__m128i) __builtin_ia32_pcmpestrm128 ((__v16qi)__X, __LX,
    519 						(__v16qi)__Y, __LY,
    520 						__M);
    521 }
    522 
    523 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    524 _mm_cmpestri (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M)
    525 {
    526   return __builtin_ia32_pcmpestri128 ((__v16qi)__X, __LX,
    527 				      (__v16qi)__Y, __LY,
    528 				      __M);
    529 }
    530 #else
    531 #define _mm_cmpistrm(X, Y, M)						\
    532   ((__m128i) __builtin_ia32_pcmpistrm128 ((__v16qi)(__m128i)(X),	\
    533 					  (__v16qi)(__m128i)(Y), (int)(M)))
    534 #define _mm_cmpistri(X, Y, M)						\
    535   ((int) __builtin_ia32_pcmpistri128 ((__v16qi)(__m128i)(X),		\
    536 				      (__v16qi)(__m128i)(Y), (int)(M)))
    537 
    538 #define _mm_cmpestrm(X, LX, Y, LY, M)					\
    539   ((__m128i) __builtin_ia32_pcmpestrm128 ((__v16qi)(__m128i)(X),	\
    540 					  (int)(LX), (__v16qi)(__m128i)(Y), \
    541 					  (int)(LY), (int)(M)))
    542 #define _mm_cmpestri(X, LX, Y, LY, M)					\
    543   ((int) __builtin_ia32_pcmpestri128 ((__v16qi)(__m128i)(X), (int)(LX),	\
    544 				      (__v16qi)(__m128i)(Y), (int)(LY),	\
    545 				      (int)(M)))
    546 #endif
    547 
    548 /* Intrinsics for text/string processing and reading values of
    549    EFlags.  */
    550 
    551 #ifdef __OPTIMIZE__
    552 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    553 _mm_cmpistra (__m128i __X, __m128i __Y, const int __M)
    554 {
    555   return __builtin_ia32_pcmpistria128 ((__v16qi)__X,
    556 				       (__v16qi)__Y,
    557 				       __M);
    558 }
    559 
    560 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    561 _mm_cmpistrc (__m128i __X, __m128i __Y, const int __M)
    562 {
    563   return __builtin_ia32_pcmpistric128 ((__v16qi)__X,
    564 				       (__v16qi)__Y,
    565 				       __M);
    566 }
    567 
    568 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    569 _mm_cmpistro (__m128i __X, __m128i __Y, const int __M)
    570 {
    571   return __builtin_ia32_pcmpistrio128 ((__v16qi)__X,
    572 				       (__v16qi)__Y,
    573 				       __M);
    574 }
    575 
    576 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    577 _mm_cmpistrs (__m128i __X, __m128i __Y, const int __M)
    578 {
    579   return __builtin_ia32_pcmpistris128 ((__v16qi)__X,
    580 				       (__v16qi)__Y,
    581 				       __M);
    582 }
    583 
    584 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    585 _mm_cmpistrz (__m128i __X, __m128i __Y, const int __M)
    586 {
    587   return __builtin_ia32_pcmpistriz128 ((__v16qi)__X,
    588 				       (__v16qi)__Y,
    589 				       __M);
    590 }
    591 
    592 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    593 _mm_cmpestra (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M)
    594 {
    595   return __builtin_ia32_pcmpestria128 ((__v16qi)__X, __LX,
    596 				       (__v16qi)__Y, __LY,
    597 				       __M);
    598 }
    599 
    600 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    601 _mm_cmpestrc (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M)
    602 {
    603   return __builtin_ia32_pcmpestric128 ((__v16qi)__X, __LX,
    604 				       (__v16qi)__Y, __LY,
    605 				       __M);
    606 }
    607 
    608 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    609 _mm_cmpestro (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M)
    610 {
    611   return __builtin_ia32_pcmpestrio128 ((__v16qi)__X, __LX,
    612 				       (__v16qi)__Y, __LY,
    613 				       __M);
    614 }
    615 
    616 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    617 _mm_cmpestrs (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M)
    618 {
    619   return __builtin_ia32_pcmpestris128 ((__v16qi)__X, __LX,
    620 				       (__v16qi)__Y, __LY,
    621 				       __M);
    622 }
    623 
    624 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    625 _mm_cmpestrz (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M)
    626 {
    627   return __builtin_ia32_pcmpestriz128 ((__v16qi)__X, __LX,
    628 				       (__v16qi)__Y, __LY,
    629 				       __M);
    630 }
    631 #else
    632 #define _mm_cmpistra(X, Y, M)						\
    633   ((int) __builtin_ia32_pcmpistria128 ((__v16qi)(__m128i)(X),		\
    634 				       (__v16qi)(__m128i)(Y), (int)(M)))
    635 #define _mm_cmpistrc(X, Y, M)						\
    636   ((int) __builtin_ia32_pcmpistric128 ((__v16qi)(__m128i)(X),		\
    637 				       (__v16qi)(__m128i)(Y), (int)(M)))
    638 #define _mm_cmpistro(X, Y, M)						\
    639   ((int) __builtin_ia32_pcmpistrio128 ((__v16qi)(__m128i)(X),		\
    640 				       (__v16qi)(__m128i)(Y), (int)(M)))
    641 #define _mm_cmpistrs(X, Y, M)						\
    642   ((int) __builtin_ia32_pcmpistris128 ((__v16qi)(__m128i)(X),		\
    643 				       (__v16qi)(__m128i)(Y), (int)(M)))
    644 #define _mm_cmpistrz(X, Y, M)						\
    645   ((int) __builtin_ia32_pcmpistriz128 ((__v16qi)(__m128i)(X),		\
    646 				       (__v16qi)(__m128i)(Y), (int)(M)))
    647 
    648 #define _mm_cmpestra(X, LX, Y, LY, M)					\
    649   ((int) __builtin_ia32_pcmpestria128 ((__v16qi)(__m128i)(X), (int)(LX), \
    650 				       (__v16qi)(__m128i)(Y), (int)(LY), \
    651 				       (int)(M)))
    652 #define _mm_cmpestrc(X, LX, Y, LY, M)					\
    653   ((int) __builtin_ia32_pcmpestric128 ((__v16qi)(__m128i)(X), (int)(LX), \
    654 				       (__v16qi)(__m128i)(Y), (int)(LY), \
    655 				       (int)(M)))
    656 #define _mm_cmpestro(X, LX, Y, LY, M)					\
    657   ((int) __builtin_ia32_pcmpestrio128 ((__v16qi)(__m128i)(X), (int)(LX), \
    658 				       (__v16qi)(__m128i)(Y), (int)(LY), \
    659 				       (int)(M)))
    660 #define _mm_cmpestrs(X, LX, Y, LY, M)					\
    661   ((int) __builtin_ia32_pcmpestris128 ((__v16qi)(__m128i)(X), (int)(LX), \
    662 				       (__v16qi)(__m128i)(Y), (int)(LY), \
    663 				       (int)(M)))
    664 #define _mm_cmpestrz(X, LX, Y, LY, M)					\
    665   ((int) __builtin_ia32_pcmpestriz128 ((__v16qi)(__m128i)(X), (int)(LX), \
    666 				       (__v16qi)(__m128i)(Y), (int)(LY), \
    667 				       (int)(M)))
    668 #endif
    669 
    670 /* Packed integer 64-bit comparison, zeroing or filling with ones
    671    corresponding parts of result.  */
    672 extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    673 _mm_cmpgt_epi64 (__m128i __X, __m128i __Y)
    674 {
    675   return (__m128i) __builtin_ia32_pcmpgtq ((__v2di)__X, (__v2di)__Y);
    676 }
    677 
    678 /* Calculate a number of bits set to 1.  */
    679 extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    680 _mm_popcnt_u32 (unsigned int __X)
    681 {
    682   return __builtin_popcount (__X);
    683 }
    684 
    685 #ifdef __x86_64__
    686 extern __inline long long  __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    687 _mm_popcnt_u64 (unsigned long long __X)
    688 {
    689   return __builtin_popcountll (__X);
    690 }
    691 #endif
    692 
    693 /* Accumulate CRC32 (polynomial 0x11EDC6F41) value.  */
    694 extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    695 _mm_crc32_u8 (unsigned int __C, unsigned char __V)
    696 {
    697   return __builtin_ia32_crc32qi (__C, __V);
    698 }
    699 
    700 extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    701 _mm_crc32_u16 (unsigned int __C, unsigned short __V)
    702 {
    703   return __builtin_ia32_crc32hi (__C, __V);
    704 }
    705 
    706 extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    707 _mm_crc32_u32 (unsigned int __C, unsigned int __V)
    708 {
    709   return __builtin_ia32_crc32si (__C, __V);
    710 }
    711 
    712 #ifdef __x86_64__
    713 extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
    714 _mm_crc32_u64 (unsigned long long __C, unsigned long long __V)
    715 {
    716   return __builtin_ia32_crc32di (__C, __V);
    717 }
    718 #endif
    719 
    720 #endif /* __SSE4_2__ */
    721 
    722 #endif /* __SSE4_1__ */
    723 
    724 #endif /* _SMMINTRIN_H_INCLUDED */
    725