ube错误:_mm_aeskeygenassist_si128内在要求至少-xarch = aes

时间:2016-06-10 10:50:00

标签: c++ solaris sunstudio

我在SunOS 5.11(Solaris 11.3)上使用Sun Studio 12.3。它提供了一个我不太了解的编译错误:

$ /opt/solarisstudio12.3/bin/CC -xarch=sse2 -xarch=aes -xarch=sse4_2 -c test.cxx 
"test.cxx", line 11: ube: error: _mm_aeskeygenassist_si128 intrinsic requires at least -xarch=aes.
CC: ube failed for test.cxx

添加-m64会产生同样的错误。

测试程序并不多。它只是简单地运用SSE2内在函数和AES内在函数:

$ cat test.cxx
#include <stdint.h>
#include <wmmintrin.h>
#include <emmintrin.h>
int main(int argc, char* argv[])
{
  // SSE2
  int64_t x[2];
  __m128i y = _mm_loadu_si128((__m128i*)x);

  // AES
  __m128i z = _mm_aeskeygenassist_si128(y,0);

  return 0;
}

我一直在尝试完成手册,并学习如何指定多个cpu架构功能,如SSE2,SSSE3,AES和SSE4。但我似乎无法确定如何指定多个。这是我找到的更完整页面之一:Oracle Man Page CC.1,但我显然遗漏了与-xarch相关的内容。

我做错了什么,我该如何解决?

2 个答案:

答案 0 :(得分:3)

此命令行

$ /opt/solarisstudio12.3/bin/CC -xarch=sse2 -xarch=aes -xarch=sse4_2 -c test.cxx 

将使用-xarch=sse2 -xarch=aes -xarch=sse4_2的最后一个并使编译器发出sse4_2 - 兼容的二进制文件。

Chapter 3 of the C++ User's Guide中记录了这一点:

  

3.2一般准则

     

C ++编译器选项的一些通用指南是:

     
      
  • -llib选项链接库liblib.a(或liblib.so)。在源文件和目标文件之后放置llib总是更安全   搜索库的顺序。

  •   
  • 一般情况下,编译器选项的处理是从左到右(除了在所有D之后处理-U选项)   选项),允许选择性覆盖宏选项(选项)   包括其他选项)。此规则不适用于链接器选项。

  •   
  • -features,-I -l,-L,-library,-pti,-R,-staticlib,-U,-verbose和-xprefetch选项会累积,它们不会覆盖。

  •   
  • -D选项累积。但是,同名的多个-D选项会相互覆盖。

  •   
     

编译和链接源文件,目标文件和库   它们在命令行中出现的顺序。

这样做就可以完成覆盖-fast, which expands to about 10 separate arguments等参数扩展的事情。

您应该使用-xarch=aes标记 - 最后一个或仅作为-xarch=...选项。

答案 1 :(得分:0)

我打算回答那些来自海湾合作委员会的人。在海湾合作委员会的世界中,我们-march=native和GCC定义了像-D__SSE2__-D__SSE4_1__-D__SSE4_2__-D__AES__-D__AVX__,{{1}这样的宏等等。

SunCC不像GCC那样做。它不提供像-D__BMI__这样的定义;它也没有为__SSE2__提供价值。

以下是相关Sun Studio手册和-xarch选项/说明集选项的参考:

以下是我们如何确定可以使用的标志,然后将它们转换为GCC预处理器宏。它很糟糕,但我不知道如何获得生成的代码。

-xarch

上面的回转允许我们做这样的事情(除了我们需要SSE2虽然是ADX)。

CC=...
EGREP=...

X86_CPU_FLAGS=$(isainfo -v 2>/dev/null)
SUNCC_510_OR_ABOVE=$("$CXX" -V 2>&1 | "$EGREP" -c "CC: (Sun|Studio) .* (5\.1[0-9]|5\.[2-9]|[6-9]\.)")
SUNCC_511_OR_ABOVE=$("$CXX" -V 2>&1 | "$EGREP" -c "CC: (Sun|Studio) .* (5\.1[1-9]|5\.[2-9]|[6-9]\.)")
SUNCC_512_OR_ABOVE=$("$CXX" -V 2>&1 | "$EGREP" -c "CC: (Sun|Studio) .* (5\.1[2-9]|5\.[2-9]|[6-9]\.)")
SUNCC_513_OR_ABOVE=$("$CXX" -V 2>&1 | "$EGREP" -c "CC: (Sun|Studio) .* (5\.1[3-9]|5\.[2-9]|[6-9]\.)")

SUNCC_XARCH=
if [[ ("$SUNCC_511_OR_ABOVE" -ne "0") ]]; then
    if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "sse2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE2__"); SUNCC_XARCH=sse2; fi
        if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "sse3") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE3__"); SUNCC_XARCH=ssse3; fi
        if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "ssse3") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSSE3__"); SUNCC_XARCH=ssse3; fi
        if [[ ("$SUNCC_512_OR_ABOVE" -ne "0") ]]; then
            if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "sse4.1") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE4_1__"); SUNCC_XARCH=ssse4_1; fi
            if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "sse4.2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE4_2__"); SUNCC_XARCH=ssse4_2; fi
            if [[ ("$SUNCC_513_OR_ABOVE" -ne "0") ]]; then
                if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "aes") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__AES__"); SUNCC_XARCH=aes; fi
                if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "pclmulqdq") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__PCLMUL__"); SUNCC_XARCH=aes; fi
                if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "rdrand") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__RDRND__"); SUNCC_XARCH=avx_i; fi
                if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "rdseed") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__RDSEED__"); SUNCC_XARCH=avx_i; fi
                if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "avx") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__AVX__"); SUNCC_XARCH=avx; fi
                if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "avx2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__AVX2__"); SUNCC_XARCH=avx2; fi
                if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "bmi") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__BMI__"); SUNCC_XARCH=avx2; fi
                if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "bmi2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__BMI2__"); SUNCC_XARCH=avx2; fi
                if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "adx") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__ADX__"); SUNCC_XARCH=avx2_i; fi        
            fi
        fi
    fi
fi
PLATFORM_CXXFLAGS+=("-xarch=$SUNCC_XARCH")

如果没有这些旋转,我们会在测试期间使用内联汇编和内在函数不断地使12.1到12.3编译器崩溃。

运行脚本的结果为我们提供了#if (_MSC_VER >= 1700) || defined(__RDRND__) uint64_t val; if(_rdrand64_step(&val)) { // Use RDRAND value } #endif CFLAGS的配方。以下是第4代Core i5。 XEON产生不同的结果,第五代Core i5也是如此。例如,第5代Core i5将CXXFLAGS并使用ADX

-xarch=avx_i