一段时间以来,我一直在为这个问题挠头。我正在使用 GCC 4.4.4(我已经检查了 GCC 3.4.6、4.4.6 和 4.6.3。)并且在我正在做的一些数学运算中遇到了问题。我将示例编译为以下独立程序:
#include <stdio.h>
int main()
{
float something[4] = { 1.0f, 2.0f, 3.0f, 4.0f };
asm volatile
(
"movups %0, %%xmm0 \n\t"
"movups %%xmm0, %0 \n\t"
: "=m" (*something)
:
: "memory", "xmm0"
);
printf("%.0f %.0f %.0f %.0f\n",
something[0], something[1], something[2], something[3]);
return 0;
}
简单编译
gcc -msse -O -o something something.c
它通过以某种方式破坏第一个数组元素而失败(除了我尝试过的 GCC 3.4.6 ......在那里,它工作正常)。在我的一生中,我看不出这里有什么根本上的错误。
相反,如果我将有问题的 ASM 块更改为
_mm_storeu_ps(something, _mm_loadu_ps(something));
它工作正常。我检查了生成的汇编代码,发现带有 ASM 块的版本少了一个导致 SSE 部分的存储操作:
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $64, %esp
movl $0x40000000, 52(%esp)
movl $0x40400000, 56(%esp)
movl $0x40800000, 60(%esp)
与更正确的(使用内在函数的代码)相比:
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $64, %esp
movl $0x3f800000, 48(%esp)
movl $0x40000000, 52(%esp)
movl $0x40400000, 56(%esp)
movl $0x40800000, 60(%esp)
WTF 对我或 GCC 有什么问题吗?
(注意,这是一个简明扼要的示例,显示了我所追踪的根本问题。ASM 块和 volatile 关键字的原因似乎并没有真正解决我提出的主要问题在这里转发。)