assembly - 使用 CPUID 测试 SSE2 还是尝试 SSE2 指令和 SIGILL?

标签 assembly sse2 cpuid

我正在查看一些执行以下操作的库代码。 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;
}

根据 Intel® 64 and IA-32 Architectures Software Developer Manual 调用 CPUID 并测试 EDX 的第 26 位是正确的,第 2 卷,图 3-8,第 3-192 页。所以我不确定 TrySSE2 部分...

我看过其他类似的问题,例如 Determine processor support for SSE2? 。他们没有人说测试 EDX:26 不可靠。

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

最佳答案

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

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

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

请参阅此处了解更多信息:http://wiki.osdev.org/SSE#Checking_for_SSE

关于assembly - 使用 CPUID 测试 SSE2 还是尝试 SSE2 指令和 SIGILL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32087056/

相关文章:

linux - 关于 Lubuntu 16.04 (i386) ICOP 板中的 QT 创建者

c - 引导加载程序上的图形

android - 如何在 Android 项目中使用 ARM 汇编代码?

assembly - GNU 程序集引导加载程序无法引导

c++ - 在 C++ 中将一个 int 打包到一个位域中

c++ - 编译时重复语法错误

使用 C 中的内联汇编检查 RFLAGS 中的 ID 标志

c - 入口点在正确的地方吗?

assembly - orpd等SSE2指令的意义何在?

c - SSE指令MOVSD(扩展:x86,x86-64上的浮点标量和 vector 运算)