在我们的代码库中,我发现这个代码片段用于在x87上进行快速,向负无限1舍入:
inline int my_int(double x)
{
int r;
#ifdef _GCC_
asm ("fldl %1\n"
"fistpl %0\n"
:"=m"(r)
:"m"(x));
#else
// ...
#endif
return r;
}
Run Code Online (Sandbox Code Playgroud)
我不是非常熟悉GCC扩展汇编语法,但是从我从文档中收集到的内容:
r 必须是一个记忆位置,我在写回东西;x 必须是一个内存位置,数据来自哪里.现在,来回答我的问题:最终FPU堆栈是平衡的,但是如果所有8个位置都已经在使用并且我已经溢出呢?编译器如何知道它不能信任ST(7)它离开它的位置?应该添加一些clobber吗?
编辑我试图st(7)在clobber列表中指定它似乎影响codegen,现在我将等待对此事实的一些确认.
作为旁注:看看lrintglibc和MinGW 中的准系统的实现,我看到了类似的东西
__asm__ __volatile__ ("fistpl %0"
: "=m" (retval)
: "t" (x)
: "st");
Run Code Online (Sandbox Code Playgroud)
我们要求输入直接放在哪里ST(0)(避免这种情况无用fldl); 什么是"st"clobber?文档似乎只提到t(即堆栈的顶部).
我写了一个这样的矢量结构:
struct vector {
float x1, x2, x3, x4;
};
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个函数,它使用向量使用内联汇编执行一些操作:
struct vector *adding(const struct vector v1[], const struct vector v2[], int size) {
struct vector vec[size];
int i;
for(i = 0; i < size; i++) {
asm(
"FLDL %4 \n" //v1.x1
"FADDL %8 \n" //v2.x1
"FSTL %0 \n"
"FLDL %5 \n" //v1.x2
"FADDL %9 \n" //v2.x2
"FSTL %1 \n"
"FLDL %6 \n" //v1.x3
"FADDL %10 \n" //v2.x3
"FSTL %2 \n"
"FLDL %7 \n" //v1.x4
"FADDL %11 \n" //v2.x4
"FSTL …Run Code Online (Sandbox Code Playgroud)