1/* Copyright (C) 2007-2020 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/* Implemented from the specification included in the Intel C++ Compiler 25 User Guide and Reference, version 10.0. */ 26 27#ifndef _SMMINTRIN_H_INCLUDED 28#define _SMMINTRIN_H_INCLUDED 29 30/* We need definitions from the SSSE3, SSE3, SSE2 and SSE header 31 files. */ 32#include <tmmintrin.h> 33 34#ifndef __SSE4_1__ 35#pragma GCC push_options 36#pragma GCC target("sse4.1") 37#define __DISABLE_SSE4_1__ 38#endif /* __SSE4_1__ */ 39 40/* Rounding mode macros. */ 41#define _MM_FROUND_TO_NEAREST_INT 0x00 42#define _MM_FROUND_TO_NEG_INF 0x01 43#define _MM_FROUND_TO_POS_INF 0x02 44#define _MM_FROUND_TO_ZERO 0x03 45#define _MM_FROUND_CUR_DIRECTION 0x04 46 47#define _MM_FROUND_RAISE_EXC 0x00 48#define _MM_FROUND_NO_EXC 0x08 49 50#define _MM_FROUND_NINT \ 51 (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_RAISE_EXC) 52#define _MM_FROUND_FLOOR \ 53 (_MM_FROUND_TO_NEG_INF | _MM_FROUND_RAISE_EXC) 54#define _MM_FROUND_CEIL \ 55 (_MM_FROUND_TO_POS_INF | _MM_FROUND_RAISE_EXC) 56#define _MM_FROUND_TRUNC \ 57 (_MM_FROUND_TO_ZERO | _MM_FROUND_RAISE_EXC) 58#define _MM_FROUND_RINT \ 59 (_MM_FROUND_CUR_DIRECTION | _MM_FROUND_RAISE_EXC) 60#define _MM_FROUND_NEARBYINT \ 61 (_MM_FROUND_CUR_DIRECTION | _MM_FROUND_NO_EXC) 62 63/* Test Instruction */ 64/* Packed integer 128-bit bitwise comparison. Return 1 if 65 (__V & __M) == 0. */ 66extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 67_mm_testz_si128 (__m128i __M, __m128i __V) 68{ 69 return __builtin_ia32_ptestz128 ((__v2di)__M, (__v2di)__V); 70} 71 72/* Packed integer 128-bit bitwise comparison. Return 1 if 73 (__V & ~__M) == 0. */ 74extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 75_mm_testc_si128 (__m128i __M, __m128i __V) 76{ 77 return __builtin_ia32_ptestc128 ((__v2di)__M, (__v2di)__V); 78} 79 80/* Packed integer 128-bit bitwise comparison. Return 1 if 81 (__V & __M) != 0 && (__V & ~__M) != 0. */ 82extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 83_mm_testnzc_si128 (__m128i __M, __m128i __V) 84{ 85 return __builtin_ia32_ptestnzc128 ((__v2di)__M, (__v2di)__V); 86} 87 88/* Macros for packed integer 128-bit comparison intrinsics. */ 89#define _mm_test_all_zeros(M, V) _mm_testz_si128 ((M), (V)) 90 91#define _mm_test_all_ones(V) \ 92 _mm_testc_si128 ((V), _mm_cmpeq_epi32 ((V), (V))) 93 94#define _mm_test_mix_ones_zeros(M, V) _mm_testnzc_si128 ((M), (V)) 95 96/* Packed/scalar double precision floating point rounding. */ 97 98#ifdef __OPTIMIZE__ 99extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 100_mm_round_pd (__m128d __V, const int __M) 101{ 102 return (__m128d) __builtin_ia32_roundpd ((__v2df)__V, __M); 103} 104 105extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 106_mm_round_sd(__m128d __D, __m128d __V, const int __M) 107{ 108 return (__m128d) __builtin_ia32_roundsd ((__v2df)__D, 109 (__v2df)__V, 110 __M); 111} 112#else 113#define _mm_round_pd(V, M) \ 114 ((__m128d) __builtin_ia32_roundpd ((__v2df)(__m128d)(V), (int)(M))) 115 116#define _mm_round_sd(D, V, M) \ 117 ((__m128d) __builtin_ia32_roundsd ((__v2df)(__m128d)(D), \ 118 (__v2df)(__m128d)(V), (int)(M))) 119#endif 120 121/* Packed/scalar single precision floating point rounding. */ 122 123#ifdef __OPTIMIZE__ 124extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 125_mm_round_ps (__m128 __V, const int __M) 126{ 127 return (__m128) __builtin_ia32_roundps ((__v4sf)__V, __M); 128} 129 130extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 131_mm_round_ss (__m128 __D, __m128 __V, const int __M) 132{ 133 return (__m128) __builtin_ia32_roundss ((__v4sf)__D, 134 (__v4sf)__V, 135 __M); 136} 137#else 138#define _mm_round_ps(V, M) \ 139 ((__m128) __builtin_ia32_roundps ((__v4sf)(__m128)(V), (int)(M))) 140 141#define _mm_round_ss(D, V, M) \ 142 ((__m128) __builtin_ia32_roundss ((__v4sf)(__m128)(D), \ 143 (__v4sf)(__m128)(V), (int)(M))) 144#endif 145 146/* Macros for ceil/floor intrinsics. */ 147#define _mm_ceil_pd(V) _mm_round_pd ((V), _MM_FROUND_CEIL) 148#define _mm_ceil_sd(D, V) _mm_round_sd ((D), (V), _MM_FROUND_CEIL) 149 150#define _mm_floor_pd(V) _mm_round_pd((V), _MM_FROUND_FLOOR) 151#define _mm_floor_sd(D, V) _mm_round_sd ((D), (V), _MM_FROUND_FLOOR) 152 153#define _mm_ceil_ps(V) _mm_round_ps ((V), _MM_FROUND_CEIL) 154#define _mm_ceil_ss(D, V) _mm_round_ss ((D), (V), _MM_FROUND_CEIL) 155 156#define _mm_floor_ps(V) _mm_round_ps ((V), _MM_FROUND_FLOOR) 157#define _mm_floor_ss(D, V) _mm_round_ss ((D), (V), _MM_FROUND_FLOOR) 158 159/* SSE4.1 */ 160 161/* Integer blend instructions - select data from 2 sources using 162 constant/variable mask. */ 163 164#ifdef __OPTIMIZE__ 165extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 166_mm_blend_epi16 (__m128i __X, __m128i __Y, const int __M) 167{ 168 return (__m128i) __builtin_ia32_pblendw128 ((__v8hi)__X, 169 (__v8hi)__Y, 170 __M); 171} 172#else 173#define _mm_blend_epi16(X, Y, M) \ 174 ((__m128i) __builtin_ia32_pblendw128 ((__v8hi)(__m128i)(X), \ 175 (__v8hi)(__m128i)(Y), (int)(M))) 176#endif 177 178extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 179_mm_blendv_epi8 (__m128i __X, __m128i __Y, __m128i __M) 180{ 181 return (__m128i) __builtin_ia32_pblendvb128 ((__v16qi)__X, 182 (__v16qi)__Y, 183 (__v16qi)__M); 184} 185 186/* Single precision floating point blend instructions - select data 187 from 2 sources using constant/variable mask. */ 188 189#ifdef __OPTIMIZE__ 190extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 191_mm_blend_ps (__m128 __X, __m128 __Y, const int __M) 192{ 193 return (__m128) __builtin_ia32_blendps ((__v4sf)__X, 194 (__v4sf)__Y, 195 __M); 196} 197#else 198#define _mm_blend_ps(X, Y, M) \ 199 ((__m128) __builtin_ia32_blendps ((__v4sf)(__m128)(X), \ 200 (__v4sf)(__m128)(Y), (int)(M))) 201#endif 202 203extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 204_mm_blendv_ps (__m128 __X, __m128 __Y, __m128 __M) 205{ 206 return (__m128) __builtin_ia32_blendvps ((__v4sf)__X, 207 (__v4sf)__Y, 208 (__v4sf)__M); 209} 210 211/* Double precision floating point blend instructions - select data 212 from 2 sources using constant/variable mask. */ 213 214#ifdef __OPTIMIZE__ 215extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 216_mm_blend_pd (__m128d __X, __m128d __Y, const int __M) 217{ 218 return (__m128d) __builtin_ia32_blendpd ((__v2df)__X, 219 (__v2df)__Y, 220 __M); 221} 222#else 223#define _mm_blend_pd(X, Y, M) \ 224 ((__m128d) __builtin_ia32_blendpd ((__v2df)(__m128d)(X), \ 225 (__v2df)(__m128d)(Y), (int)(M))) 226#endif 227 228extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 229_mm_blendv_pd (__m128d __X, __m128d __Y, __m128d __M) 230{ 231 return (__m128d) __builtin_ia32_blendvpd ((__v2df)__X, 232 (__v2df)__Y, 233 (__v2df)__M); 234} 235 236/* Dot product instructions with mask-defined summing and zeroing parts 237 of result. */ 238 239#ifdef __OPTIMIZE__ 240extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 241_mm_dp_ps (__m128 __X, __m128 __Y, const int __M) 242{ 243 return (__m128) __builtin_ia32_dpps ((__v4sf)__X, 244 (__v4sf)__Y, 245 __M); 246} 247 248extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 249_mm_dp_pd (__m128d __X, __m128d __Y, const int __M) 250{ 251 return (__m128d) __builtin_ia32_dppd ((__v2df)__X, 252 (__v2df)__Y, 253 __M); 254} 255#else 256#define _mm_dp_ps(X, Y, M) \ 257 ((__m128) __builtin_ia32_dpps ((__v4sf)(__m128)(X), \ 258 (__v4sf)(__m128)(Y), (int)(M))) 259 260#define _mm_dp_pd(X, Y, M) \ 261 ((__m128d) __builtin_ia32_dppd ((__v2df)(__m128d)(X), \ 262 (__v2df)(__m128d)(Y), (int)(M))) 263#endif 264 265/* Packed integer 64-bit comparison, zeroing or filling with ones 266 corresponding parts of result. */ 267extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 268_mm_cmpeq_epi64 (__m128i __X, __m128i __Y) 269{ 270 return (__m128i) ((__v2di)__X == (__v2di)__Y); 271} 272 273/* Min/max packed integer instructions. */ 274 275extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 276_mm_min_epi8 (__m128i __X, __m128i __Y) 277{ 278 return (__m128i) __builtin_ia32_pminsb128 ((__v16qi)__X, (__v16qi)__Y); 279} 280 281extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 282_mm_max_epi8 (__m128i __X, __m128i __Y) 283{ 284 return (__m128i) __builtin_ia32_pmaxsb128 ((__v16qi)__X, (__v16qi)__Y); 285} 286 287extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 288_mm_min_epu16 (__m128i __X, __m128i __Y) 289{ 290 return (__m128i) __builtin_ia32_pminuw128 ((__v8hi)__X, (__v8hi)__Y); 291} 292 293extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 294_mm_max_epu16 (__m128i __X, __m128i __Y) 295{ 296 return (__m128i) __builtin_ia32_pmaxuw128 ((__v8hi)__X, (__v8hi)__Y); 297} 298 299extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 300_mm_min_epi32 (__m128i __X, __m128i __Y) 301{ 302 return (__m128i) __builtin_ia32_pminsd128 ((__v4si)__X, (__v4si)__Y); 303} 304 305extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 306_mm_max_epi32 (__m128i __X, __m128i __Y) 307{ 308 return (__m128i) __builtin_ia32_pmaxsd128 ((__v4si)__X, (__v4si)__Y); 309} 310 311extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 312_mm_min_epu32 (__m128i __X, __m128i __Y) 313{ 314 return (__m128i) __builtin_ia32_pminud128 ((__v4si)__X, (__v4si)__Y); 315} 316 317extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 318_mm_max_epu32 (__m128i __X, __m128i __Y) 319{ 320 return (__m128i) __builtin_ia32_pmaxud128 ((__v4si)__X, (__v4si)__Y); 321} 322 323/* Packed integer 32-bit multiplication with truncation of upper 324 halves of results. */ 325extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 326_mm_mullo_epi32 (__m128i __X, __m128i __Y) 327{ 328 return (__m128i) ((__v4su)__X * (__v4su)__Y); 329} 330 331/* Packed integer 32-bit multiplication of 2 pairs of operands 332 with two 64-bit results. */ 333extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 334_mm_mul_epi32 (__m128i __X, __m128i __Y) 335{ 336 return (__m128i) __builtin_ia32_pmuldq128 ((__v4si)__X, (__v4si)__Y); 337} 338 339/* Insert single precision float into packed single precision array 340 element selected by index N. The bits [7-6] of N define S 341 index, the bits [5-4] define D index, and bits [3-0] define 342 zeroing mask for D. */ 343 344#ifdef __OPTIMIZE__ 345extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 346_mm_insert_ps (__m128 __D, __m128 __S, const int __N) 347{ 348 return (__m128) __builtin_ia32_insertps128 ((__v4sf)__D, 349 (__v4sf)__S, 350 __N); 351} 352#else 353#define _mm_insert_ps(D, S, N) \ 354 ((__m128) __builtin_ia32_insertps128 ((__v4sf)(__m128)(D), \ 355 (__v4sf)(__m128)(S), (int)(N))) 356#endif 357 358/* Helper macro to create the N value for _mm_insert_ps. */ 359#define _MM_MK_INSERTPS_NDX(S, D, M) (((S) << 6) | ((D) << 4) | (M)) 360 361/* Extract binary representation of single precision float from packed 362 single precision array element of X selected by index N. */ 363 364#ifdef __OPTIMIZE__ 365extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 366_mm_extract_ps (__m128 __X, const int __N) 367{ 368 union { int __i; float __f; } __tmp; 369 __tmp.__f = __builtin_ia32_vec_ext_v4sf ((__v4sf)__X, __N); 370 return __tmp.__i; 371} 372#else 373#define _mm_extract_ps(X, N) \ 374 (__extension__ \ 375 ({ \ 376 union { int __i; float __f; } __tmp; \ 377 __tmp.__f = __builtin_ia32_vec_ext_v4sf ((__v4sf)(__m128)(X), \ 378 (int)(N)); \ 379 __tmp.__i; \ 380 })) 381#endif 382 383/* Extract binary representation of single precision float into 384 D from packed single precision array element of S selected 385 by index N. */ 386#define _MM_EXTRACT_FLOAT(D, S, N) \ 387 { (D) = __builtin_ia32_vec_ext_v4sf ((__v4sf)(S), (N)); } 388 389/* Extract specified single precision float element into the lower 390 part of __m128. */ 391#define _MM_PICK_OUT_PS(X, N) \ 392 _mm_insert_ps (_mm_setzero_ps (), (X), \ 393 _MM_MK_INSERTPS_NDX ((N), 0, 0x0e)) 394 395/* Insert integer, S, into packed integer array element of D 396 selected by index N. */ 397 398#ifdef __OPTIMIZE__ 399extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 400_mm_insert_epi8 (__m128i __D, int __S, const int __N) 401{ 402 return (__m128i) __builtin_ia32_vec_set_v16qi ((__v16qi)__D, 403 __S, __N); 404} 405 406extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 407_mm_insert_epi32 (__m128i __D, int __S, const int __N) 408{ 409 return (__m128i) __builtin_ia32_vec_set_v4si ((__v4si)__D, 410 __S, __N); 411} 412 413#ifdef __x86_64__ 414extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 415_mm_insert_epi64 (__m128i __D, long long __S, const int __N) 416{ 417 return (__m128i) __builtin_ia32_vec_set_v2di ((__v2di)__D, 418 __S, __N); 419} 420#endif 421#else 422#define _mm_insert_epi8(D, S, N) \ 423 ((__m128i) __builtin_ia32_vec_set_v16qi ((__v16qi)(__m128i)(D), \ 424 (int)(S), (int)(N))) 425 426#define _mm_insert_epi32(D, S, N) \ 427 ((__m128i) __builtin_ia32_vec_set_v4si ((__v4si)(__m128i)(D), \ 428 (int)(S), (int)(N))) 429 430#ifdef __x86_64__ 431#define _mm_insert_epi64(D, S, N) \ 432 ((__m128i) __builtin_ia32_vec_set_v2di ((__v2di)(__m128i)(D), \ 433 (long long)(S), (int)(N))) 434#endif 435#endif 436 437/* Extract integer from packed integer array element of X selected by 438 index N. */ 439 440#ifdef __OPTIMIZE__ 441extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 442_mm_extract_epi8 (__m128i __X, const int __N) 443{ 444 return (unsigned char) __builtin_ia32_vec_ext_v16qi ((__v16qi)__X, __N); 445} 446 447extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 448_mm_extract_epi32 (__m128i __X, const int __N) 449{ 450 return __builtin_ia32_vec_ext_v4si ((__v4si)__X, __N); 451} 452 453#ifdef __x86_64__ 454extern __inline long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 455_mm_extract_epi64 (__m128i __X, const int __N) 456{ 457 return __builtin_ia32_vec_ext_v2di ((__v2di)__X, __N); 458} 459#endif 460#else 461#define _mm_extract_epi8(X, N) \ 462 ((int) (unsigned char) __builtin_ia32_vec_ext_v16qi ((__v16qi)(__m128i)(X), (int)(N))) 463#define _mm_extract_epi32(X, N) \ 464 ((int) __builtin_ia32_vec_ext_v4si ((__v4si)(__m128i)(X), (int)(N))) 465 466#ifdef __x86_64__ 467#define _mm_extract_epi64(X, N) \ 468 ((long long) __builtin_ia32_vec_ext_v2di ((__v2di)(__m128i)(X), (int)(N))) 469#endif 470#endif 471 472/* Return horizontal packed word minimum and its index in bits [15:0] 473 and bits [18:16] respectively. */ 474extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 475_mm_minpos_epu16 (__m128i __X) 476{ 477 return (__m128i) __builtin_ia32_phminposuw128 ((__v8hi)__X); 478} 479 480/* Packed integer sign-extension. */ 481 482extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 483_mm_cvtepi8_epi32 (__m128i __X) 484{ 485 return (__m128i) __builtin_ia32_pmovsxbd128 ((__v16qi)__X); 486} 487 488extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 489_mm_cvtepi16_epi32 (__m128i __X) 490{ 491 return (__m128i) __builtin_ia32_pmovsxwd128 ((__v8hi)__X); 492} 493 494extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 495_mm_cvtepi8_epi64 (__m128i __X) 496{ 497 return (__m128i) __builtin_ia32_pmovsxbq128 ((__v16qi)__X); 498} 499 500extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 501_mm_cvtepi32_epi64 (__m128i __X) 502{ 503 return (__m128i) __builtin_ia32_pmovsxdq128 ((__v4si)__X); 504} 505 506extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 507_mm_cvtepi16_epi64 (__m128i __X) 508{ 509 return (__m128i) __builtin_ia32_pmovsxwq128 ((__v8hi)__X); 510} 511 512extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 513_mm_cvtepi8_epi16 (__m128i __X) 514{ 515 return (__m128i) __builtin_ia32_pmovsxbw128 ((__v16qi)__X); 516} 517 518/* Packed integer zero-extension. */ 519 520extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 521_mm_cvtepu8_epi32 (__m128i __X) 522{ 523 return (__m128i) __builtin_ia32_pmovzxbd128 ((__v16qi)__X); 524} 525 526extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 527_mm_cvtepu16_epi32 (__m128i __X) 528{ 529 return (__m128i) __builtin_ia32_pmovzxwd128 ((__v8hi)__X); 530} 531 532extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 533_mm_cvtepu8_epi64 (__m128i __X) 534{ 535 return (__m128i) __builtin_ia32_pmovzxbq128 ((__v16qi)__X); 536} 537 538extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 539_mm_cvtepu32_epi64 (__m128i __X) 540{ 541 return (__m128i) __builtin_ia32_pmovzxdq128 ((__v4si)__X); 542} 543 544extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 545_mm_cvtepu16_epi64 (__m128i __X) 546{ 547 return (__m128i) __builtin_ia32_pmovzxwq128 ((__v8hi)__X); 548} 549 550extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 551_mm_cvtepu8_epi16 (__m128i __X) 552{ 553 return (__m128i) __builtin_ia32_pmovzxbw128 ((__v16qi)__X); 554} 555 556/* Pack 8 double words from 2 operands into 8 words of result with 557 unsigned saturation. */ 558extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 559_mm_packus_epi32 (__m128i __X, __m128i __Y) 560{ 561 return (__m128i) __builtin_ia32_packusdw128 ((__v4si)__X, (__v4si)__Y); 562} 563 564/* Sum absolute 8-bit integer difference of adjacent groups of 4 565 byte integers in the first 2 operands. Starting offsets within 566 operands are determined by the 3rd mask operand. */ 567 568#ifdef __OPTIMIZE__ 569extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 570_mm_mpsadbw_epu8 (__m128i __X, __m128i __Y, const int __M) 571{ 572 return (__m128i) __builtin_ia32_mpsadbw128 ((__v16qi)__X, 573 (__v16qi)__Y, __M); 574} 575#else 576#define _mm_mpsadbw_epu8(X, Y, M) \ 577 ((__m128i) __builtin_ia32_mpsadbw128 ((__v16qi)(__m128i)(X), \ 578 (__v16qi)(__m128i)(Y), (int)(M))) 579#endif 580 581/* Load double quadword using non-temporal aligned hint. */ 582extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 583_mm_stream_load_si128 (__m128i *__X) 584{ 585 return (__m128i) __builtin_ia32_movntdqa ((__v2di *) __X); 586} 587 588#ifndef __SSE4_2__ 589#pragma GCC push_options 590#pragma GCC target("sse4.2") 591#define __DISABLE_SSE4_2__ 592#endif /* __SSE4_2__ */ 593 594/* These macros specify the source data format. */ 595#define _SIDD_UBYTE_OPS 0x00 596#define _SIDD_UWORD_OPS 0x01 597#define _SIDD_SBYTE_OPS 0x02 598#define _SIDD_SWORD_OPS 0x03 599 600/* These macros specify the comparison operation. */ 601#define _SIDD_CMP_EQUAL_ANY 0x00 602#define _SIDD_CMP_RANGES 0x04 603#define _SIDD_CMP_EQUAL_EACH 0x08 604#define _SIDD_CMP_EQUAL_ORDERED 0x0c 605 606/* These macros specify the polarity. */ 607#define _SIDD_POSITIVE_POLARITY 0x00 608#define _SIDD_NEGATIVE_POLARITY 0x10 609#define _SIDD_MASKED_POSITIVE_POLARITY 0x20 610#define _SIDD_MASKED_NEGATIVE_POLARITY 0x30 611 612/* These macros specify the output selection in _mm_cmpXstri (). */ 613#define _SIDD_LEAST_SIGNIFICANT 0x00 614#define _SIDD_MOST_SIGNIFICANT 0x40 615 616/* These macros specify the output selection in _mm_cmpXstrm (). */ 617#define _SIDD_BIT_MASK 0x00 618#define _SIDD_UNIT_MASK 0x40 619 620/* Intrinsics for text/string processing. */ 621 622#ifdef __OPTIMIZE__ 623extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 624_mm_cmpistrm (__m128i __X, __m128i __Y, const int __M) 625{ 626 return (__m128i) __builtin_ia32_pcmpistrm128 ((__v16qi)__X, 627 (__v16qi)__Y, 628 __M); 629} 630 631extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 632_mm_cmpistri (__m128i __X, __m128i __Y, const int __M) 633{ 634 return __builtin_ia32_pcmpistri128 ((__v16qi)__X, 635 (__v16qi)__Y, 636 __M); 637} 638 639extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 640_mm_cmpestrm (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M) 641{ 642 return (__m128i) __builtin_ia32_pcmpestrm128 ((__v16qi)__X, __LX, 643 (__v16qi)__Y, __LY, 644 __M); 645} 646 647extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 648_mm_cmpestri (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M) 649{ 650 return __builtin_ia32_pcmpestri128 ((__v16qi)__X, __LX, 651 (__v16qi)__Y, __LY, 652 __M); 653} 654#else 655#define _mm_cmpistrm(X, Y, M) \ 656 ((__m128i) __builtin_ia32_pcmpistrm128 ((__v16qi)(__m128i)(X), \ 657 (__v16qi)(__m128i)(Y), (int)(M))) 658#define _mm_cmpistri(X, Y, M) \ 659 ((int) __builtin_ia32_pcmpistri128 ((__v16qi)(__m128i)(X), \ 660 (__v16qi)(__m128i)(Y), (int)(M))) 661 662#define _mm_cmpestrm(X, LX, Y, LY, M) \ 663 ((__m128i) __builtin_ia32_pcmpestrm128 ((__v16qi)(__m128i)(X), \ 664 (int)(LX), (__v16qi)(__m128i)(Y), \ 665 (int)(LY), (int)(M))) 666#define _mm_cmpestri(X, LX, Y, LY, M) \ 667 ((int) __builtin_ia32_pcmpestri128 ((__v16qi)(__m128i)(X), (int)(LX), \ 668 (__v16qi)(__m128i)(Y), (int)(LY), \ 669 (int)(M))) 670#endif 671 672/* Intrinsics for text/string processing and reading values of 673 EFlags. */ 674 675#ifdef __OPTIMIZE__ 676extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 677_mm_cmpistra (__m128i __X, __m128i __Y, const int __M) 678{ 679 return __builtin_ia32_pcmpistria128 ((__v16qi)__X, 680 (__v16qi)__Y, 681 __M); 682} 683 684extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 685_mm_cmpistrc (__m128i __X, __m128i __Y, const int __M) 686{ 687 return __builtin_ia32_pcmpistric128 ((__v16qi)__X, 688 (__v16qi)__Y, 689 __M); 690} 691 692extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 693_mm_cmpistro (__m128i __X, __m128i __Y, const int __M) 694{ 695 return __builtin_ia32_pcmpistrio128 ((__v16qi)__X, 696 (__v16qi)__Y, 697 __M); 698} 699 700extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 701_mm_cmpistrs (__m128i __X, __m128i __Y, const int __M) 702{ 703 return __builtin_ia32_pcmpistris128 ((__v16qi)__X, 704 (__v16qi)__Y, 705 __M); 706} 707 708extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 709_mm_cmpistrz (__m128i __X, __m128i __Y, const int __M) 710{ 711 return __builtin_ia32_pcmpistriz128 ((__v16qi)__X, 712 (__v16qi)__Y, 713 __M); 714} 715 716extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 717_mm_cmpestra (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M) 718{ 719 return __builtin_ia32_pcmpestria128 ((__v16qi)__X, __LX, 720 (__v16qi)__Y, __LY, 721 __M); 722} 723 724extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 725_mm_cmpestrc (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M) 726{ 727 return __builtin_ia32_pcmpestric128 ((__v16qi)__X, __LX, 728 (__v16qi)__Y, __LY, 729 __M); 730} 731 732extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 733_mm_cmpestro (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M) 734{ 735 return __builtin_ia32_pcmpestrio128 ((__v16qi)__X, __LX, 736 (__v16qi)__Y, __LY, 737 __M); 738} 739 740extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 741_mm_cmpestrs (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M) 742{ 743 return __builtin_ia32_pcmpestris128 ((__v16qi)__X, __LX, 744 (__v16qi)__Y, __LY, 745 __M); 746} 747 748extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 749_mm_cmpestrz (__m128i __X, int __LX, __m128i __Y, int __LY, const int __M) 750{ 751 return __builtin_ia32_pcmpestriz128 ((__v16qi)__X, __LX, 752 (__v16qi)__Y, __LY, 753 __M); 754} 755#else 756#define _mm_cmpistra(X, Y, M) \ 757 ((int) __builtin_ia32_pcmpistria128 ((__v16qi)(__m128i)(X), \ 758 (__v16qi)(__m128i)(Y), (int)(M))) 759#define _mm_cmpistrc(X, Y, M) \ 760 ((int) __builtin_ia32_pcmpistric128 ((__v16qi)(__m128i)(X), \ 761 (__v16qi)(__m128i)(Y), (int)(M))) 762#define _mm_cmpistro(X, Y, M) \ 763 ((int) __builtin_ia32_pcmpistrio128 ((__v16qi)(__m128i)(X), \ 764 (__v16qi)(__m128i)(Y), (int)(M))) 765#define _mm_cmpistrs(X, Y, M) \ 766 ((int) __builtin_ia32_pcmpistris128 ((__v16qi)(__m128i)(X), \ 767 (__v16qi)(__m128i)(Y), (int)(M))) 768#define _mm_cmpistrz(X, Y, M) \ 769 ((int) __builtin_ia32_pcmpistriz128 ((__v16qi)(__m128i)(X), \ 770 (__v16qi)(__m128i)(Y), (int)(M))) 771 772#define _mm_cmpestra(X, LX, Y, LY, M) \ 773 ((int) __builtin_ia32_pcmpestria128 ((__v16qi)(__m128i)(X), (int)(LX), \ 774 (__v16qi)(__m128i)(Y), (int)(LY), \ 775 (int)(M))) 776#define _mm_cmpestrc(X, LX, Y, LY, M) \ 777 ((int) __builtin_ia32_pcmpestric128 ((__v16qi)(__m128i)(X), (int)(LX), \ 778 (__v16qi)(__m128i)(Y), (int)(LY), \ 779 (int)(M))) 780#define _mm_cmpestro(X, LX, Y, LY, M) \ 781 ((int) __builtin_ia32_pcmpestrio128 ((__v16qi)(__m128i)(X), (int)(LX), \ 782 (__v16qi)(__m128i)(Y), (int)(LY), \ 783 (int)(M))) 784#define _mm_cmpestrs(X, LX, Y, LY, M) \ 785 ((int) __builtin_ia32_pcmpestris128 ((__v16qi)(__m128i)(X), (int)(LX), \ 786 (__v16qi)(__m128i)(Y), (int)(LY), \ 787 (int)(M))) 788#define _mm_cmpestrz(X, LX, Y, LY, M) \ 789 ((int) __builtin_ia32_pcmpestriz128 ((__v16qi)(__m128i)(X), (int)(LX), \ 790 (__v16qi)(__m128i)(Y), (int)(LY), \ 791 (int)(M))) 792#endif 793 794/* Packed integer 64-bit comparison, zeroing or filling with ones 795 corresponding parts of result. */ 796extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 797_mm_cmpgt_epi64 (__m128i __X, __m128i __Y) 798{ 799 return (__m128i) ((__v2di)__X > (__v2di)__Y); 800} 801 802#ifdef __DISABLE_SSE4_2__ 803#undef __DISABLE_SSE4_2__ 804#pragma GCC pop_options 805#endif /* __DISABLE_SSE4_2__ */ 806 807#ifdef __DISABLE_SSE4_1__ 808#undef __DISABLE_SSE4_1__ 809#pragma GCC pop_options 810#endif /* __DISABLE_SSE4_1__ */ 811 812#include <popcntintrin.h> 813 814#ifndef __SSE4_1__ 815#pragma GCC push_options 816#pragma GCC target("sse4.1") 817#define __DISABLE_SSE4_1__ 818#endif /* __SSE4_1__ */ 819 820#ifndef __SSE4_2__ 821#pragma GCC push_options 822#pragma GCC target("sse4.2") 823#define __DISABLE_SSE4_2__ 824#endif /* __SSE4_1__ */ 825 826/* Accumulate CRC32 (polynomial 0x11EDC6F41) value. */ 827extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 828_mm_crc32_u8 (unsigned int __C, unsigned char __V) 829{ 830 return __builtin_ia32_crc32qi (__C, __V); 831} 832 833extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 834_mm_crc32_u16 (unsigned int __C, unsigned short __V) 835{ 836 return __builtin_ia32_crc32hi (__C, __V); 837} 838 839extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 840_mm_crc32_u32 (unsigned int __C, unsigned int __V) 841{ 842 return __builtin_ia32_crc32si (__C, __V); 843} 844 845#ifdef __x86_64__ 846extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) 847_mm_crc32_u64 (unsigned long long __C, unsigned long long __V) 848{ 849 return __builtin_ia32_crc32di (__C, __V); 850} 851#endif 852 853#ifdef __DISABLE_SSE4_2__ 854#undef __DISABLE_SSE4_2__ 855#pragma GCC pop_options 856#endif /* __DISABLE_SSE4_2__ */ 857 858#ifdef __DISABLE_SSE4_1__ 859#undef __DISABLE_SSE4_1__ 860#pragma GCC pop_options 861#endif /* __DISABLE_SSE4_1__ */ 862 863#endif /* _SMMINTRIN_H_INCLUDED */ 864