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