【问题标题】:MSVC inline assembly to GCC (with parameter and return)MSVC 内联汇编到 GCC(带参数和返回)
【发布时间】:2018-04-26 12:06:26
【问题描述】:
inline float sqrt2(float sqr)
{
    float root = 0;

    __asm
    {
    sqrtss xmm0, sqr
    movss root, xmm0
    }

    return root;
}

这是我想用 gcc x86 编译的 MSVC 编译器内联程序集,我知道 gcc 内联程序集是用 asm("asm here"); 调用的。但我完全不知道如何在其中包含参数,结果是由我只知道的“=r”获得的。

这应该会导致这样的结果:

asm("sqrtss xmm0, %1\n\t"
        "movss %0, xmm0"
        : "=r" (root)
        : "r" (sqr));

【问题讨论】:

  • 你真的需要这个吗? stdlib 版本应该由编译器自动转换成这个。
  • 这是我拥有的最简单的例子。当然,我可以将其更改为标准 sqrt,但这种方法更快。我有更多的程序集要转换,所以我想学习这个
  • 在尝试使用汇编代码智取编译器之前,您可能需要阅读以下示例:More efficient assembly code?
  • @kermitesea 我几乎愿意在几乎所有情况下都将compiler can beat your assembly 赌在-O2 上。在这种情况下,我强烈建议在诉诸组装之前先进行分析。

标签: c++ gcc assembly inline


【解决方案1】:

r 约束用于通用寄存器。 x 用于 xmm。详情请咨询manual。此外,如果您在内联 asm 中使用 mov,您可能做错了。

inline float sqrt2(float sqr)
{
    float root = 0;

    __asm__("sqrtss %1, %0" : "=x" (root) : "x" (sqr));

    return root;
}

请注意,gcc 完全能够从sqrtf 库函数调用生成sqrtss 指令。您可以使用-fno-math-errno 来消除一些小的错误检查开销。

【讨论】:

  • 非常感谢您提供非常强大的信息。肯定会检查手册ty :)
  • 请注意,如果您想使用作为 AVX 和 AVX2 一部分的 GCC clang 中的本机 FMA 函数,您需要使用 -mfma 标志。然后编译器会很乐意用适当的指令替换std::fma
猜你喜欢
  • 2012-10-20
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
相关资源
最近更新 更多