相关疑难解决方法(0)

如何用扩展的gcc程序集指定x87 FPU堆栈的破坏底部?

在我们的代码库中,我发现这个代码片段用于在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 必须是一个内存位置,数据来自哪里.
  • 没有clobber规范,因此编译器可以放心,在代码片段的末尾,寄存器就像他离开时一样.

现在,来回答我的问题:最终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(即堆栈的顶部).


  1. 是的,它取决于当前的舍入模式,在我们的应用程序中应该总是"朝向负无穷大".

c x86 assembly gcc x87

5
推荐指数
1
解决办法
440
查看次数

使用FPU和C内联汇编

我写了一个这样的矢量结构:

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)

c x86 gcc inline-assembly x87

3
推荐指数
1
解决办法
1624
查看次数

标签 统计

c ×2

gcc ×2

x86 ×2

x87 ×2

assembly ×1

inline-assembly ×1