测试SSE2使用CPUID与尝试SSE2指令和SIGILL



我正在查看执行以下操作的一些库代码。CpuId函数按预期运行。加载EAX(函数)、ECX(子函数),然后调用CPUID

struct CPUIDinfo
{
    word32 EAX;
    word32 EBX;
    word32 ECX;
    word32 EDX;
};
...
CPUIDinfo info;
CpuId(1 /*EAX=1*/, 0 /*ECX=0*, info);
if ((info.EDX & (1 << 26)) != 0)
    s_hasSSE2 = TrySSE2();

然后,这就是TrySSE2中的代码:

bool TrySSE2()
{
    /* SIG handlers in place */
    // Sets XMM0 to 0
    por xmm0, xmm0;
    #if ... Microsoft and instrinsics available ...
      // Exercises MOVD instruction
      word32 x = _mm_cvtsi128_si32(xmm0);
      return x == 0;
    #endif
    return true;
}

调用CPUID和测试EDX的26位是正确的,参见Intel®64和IA-32 Architectures Software Developer Manual, Volume 2,图3-8,page 3-192。所以我不确定TrySSE2部分…

我看过其他类似的问题,如确定处理器对SSE2的支持?没有人说测试EDX:26是不可靠的。

为什么代码调用TrySSE2而不是使用CPUID/EDX:26 ?该测试在一些非英特尔处理器上是否不可靠?

当SSE指令被添加时,它们引入了需要在上下文切换期间保存/恢复的新寄存器…由于当时的操作系统没有这样的代码,SSE指令在默认情况下是禁用的。

一旦操作系统更新为支持保存/恢复这些新寄存器,操作系统就会启用SSE指令。现在所有的操作系统都支持SSE,但我怀疑这段代码正在检查:

  • CPU支持SSE2
  • 操作系统已启用SSE2

查看更多信息:http://wiki.osdev.org/SSE#Checking_for_SSE

相关内容

  • 没有找到相关文章

最新更新