在 GCC 下使用 -std=c++11 时 __v2di 在哪里声明?

Where is __v2di declared when using -std=c++11 under GCC?

我在使用 -std=c++11 时在 GCC 4.9 下编译一些代码时遇到问题。 GCC 4.9 在 Debian 8.5 (Stable) 下提供,因此相当受欢迎。

相关代码为:

__inline __m128i
clmulepi64_si128 (__m128i a, __m128i b, const int i)
{
    asm ("pclmulqdq %2, %1, %0" : "+x"(a) : "xm"(b), "i"(i));
    return a;
}

尝试编译它会导致:

In file included from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/x86intrin.h:43:0,
                 from /usr/include/x86_64-linux-gnu/c++/4.9/bits/opt_random.h:33,
                 from /usr/include/c++/4.9/random:50,
                 from /usr/include/c++/4.9/bits/stl_algo.h:66,
                 from /usr/include/c++/4.9/algorithm:62,
                 ...
error: expected ‘)’ before ‘__builtin_ia32_pclmulqdq128’
 clmulepi64_si128 (__m128i a, __m128i b, const int i)
 ^

直到我去寻找 __builtin_ia32_pclmulqdq128:

才有意义
$ grep -IR '__builtin_ia32_pclmulqdq128' /usr/lib 2>/dev/null | grep -iv clang
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:  return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X,
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:  ((__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)(__m128i)(X),  

GCC 似乎对 __v2di 进行了中间转换,但缺少 __v2di。包括GCC的<x86intrin.h> super header 没有提供。

我无法通过搜索源文件找到 __v2di。它可能在那里,但我无法找到它。请参阅下面的 greps.

在 GCC 下 -std=c++11 时,__v2di 在哪里声明或定义?


这是另一个转折......它在没有 -std=... 的情况下工作,但它在 std=c++11:

下失败
$ make CXXFLAGS=" -DDEBUG -g3 -O0 -fPIC -march=native" vmac.o
g++ -DDEBUG -g3 -O0 -fPIC -march=native -c vmac.cpp 
$

并且:

$ make CXXFLAGS=" -DDEBUG -g3 -O0 -std=c++11 -fPIC -march=native -pipe" vmac.o
g++ -DDEBUG -g3 -O0 -std=c++11 -fPIC -march=native -pipe -c vmac.cpp
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/x86intrin.h:43:0,
                 from /usr/include/x86_64-linux-gnu/c++/4.9/bits/opt_random.h:33,
                 from /usr/include/c++/4.9/random:50,
                 from /usr/include/c++/4.9/bits/stl_algo.h:66,
                 from /usr/include/c++/4.9/algorithm:62,

$ grep -IR '__v2di' /usr/lib 2>/dev/null | grep -iv clang | grep 'define'
$

$ grep -IR '__v2di' /usr/lib 2>/dev/null | grep -iv clang | grep 'struct'
$

$ grep -IR '__v2di' /usr/lib 2>/dev/null | grep -iv clang | grep '}'                                                                              
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/emmintrin.h:  return __extension__ (__m128i)(__v2di){ __q0, __q1 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/emmintrin.h:  return __extension__ (__m128i)(__v2di){ __q0, __q1 };

$ grep -IR '__v2di' /usr/lib 2>/dev/null | grep -iv clang | grep '{'
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/emmintrin.h:  return __extension__ (__m128i)(__v2di){ __q0, __q1 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di src = __extension__ (__v2di){ 0, 0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/avx2intrin.h:  __v2di mask = __extension__ (__v2di){ ~0, ~0 };
/usr/lib/gcc/x86_64-linux-gnu/4.9.2/include/emmintrin.h:  return __extension__ (__m128i)(__v2di){ __q0, __q1 };

在我的 v6 版本中,__v2di 在 emmintrin.h 中定义为:

typedef long long __v2di __attribute__ ((__vector_size__ (16)));