我在 fp:strict 模式下使用 MSVC 进入了 C 库的超越数学函数的汇编。它们似乎都遵循相同的模式,这就是sin
.
首先有一个来自名为“disp_pentium4.inc”的文件的调度例程。它检查变量___use_sse2_mathfcns
是否已设置;如果是,则调用__sin_pentium4
,否则调用__sin_default
。
__sin_pentium4
(在“sin_pentium4.asm”中)首先将参数从 x87 fpu 传输到 xmm0 寄存器,使用 SSE2 指令执行计算,然后将结果加载回 fpu。
__sin_default
(在“sin.asm”中)将变量保存在 x87 堆栈上并简单地调用fsin
.
因此,在这两种情况下,操作数都被压入 x87 堆栈并返回,使其对调用者透明,但如果___use_sse2_mathfcns
已定义,则操作实际上是在 SSE2 而不是 x87 中执行的。
这种行为对我来说非常有趣,因为 x87 超越函数因根据实现而具有略微不同的行为而臭名昭著,而给定的 SSE2 代码应该始终给出可重现的结果。
有没有办法在编译或运行时确定将使用 SSE2 代码路径?我不擅长编写程序集,因此如果这涉及编写任何程序集,将不胜感激代码示例。