对 GASM 内联中的参数 'N' 的引用无效

Invalid reference to argument 'N' in GASM Inlining

我正在使用 Developer Studio 12.5 附带的 SunCC 编译器在 Solaris 11.3 上构建 Botan。我对库或 Solaris 不太熟悉,我需要一些努力来查找问题。

编译在一个名为 divide.cpp. I've got it reduced to the following test case. According to Oracle's GCC-style asm inlining support in Sun Studio 12 compilers 的相对良性文件上快要死了,ASM 格式正确。 Clang、GCC 和 ICC 愉快地使用代码。

$ /opt/developerstudio12.5/bin/CC -m64 -std=c++11 test.cxx -c
"test.cxx", [main]:ube: error: Invalid reference to argument '1' in GASM Inlining
CC: ube failed for test.cxx

$ cat test.cxx
#include <iostream>
#include <stdint.h>    
typedef uint64_t word;

inline word multadd(word a, word b, word* c)
{
    asm(
        "mulq %[b]          \n\t"
        "addq %[c],%[a]     \n\t"
        "adcq [=11=],%[carry]   \n\t" 

      : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*c)
      : "0"(a), "1"(b), [c]"g"(*c) : "cc");

   return a;
}

int main(int argc, char* argv[])
{
    word a, b, c, d;
    std::cin >> a >> b >> c;

    d = multadd(a, b, &c);

    return 0;
}

我找不到关于错误字符串 Invalid reference to argument 'N' in GASM Inlining 的有用信息。我在 Oracle 板上找到 sunCC chokes on inline assembler。但答案是 UBE 有问题,购买支持合同以了解更多信息。

我有三个问题:


如果我将 b 参数更改为 =m,则产生同样的错误。如果我将 b 参数更改为 =r,则产生不同的错误:

asm(
    "mulq %[b]          \n\t"
    "addq %[c],%[a]     \n\t"
    "adcq [=12=],%[carry]   \n\t"

    : [a]"=a"(a), [b]"=r"(b), [carry]"=&d"(*c)
    : "0"(a), "1"(b), [c]"g"(*c) : "cc");

结果:

$ /opt/developerstudio12.5/bin/CC  -m64 -std=c++11 test.cxx -c
Assembler: test.cxx
        "<null>", line 205 : Invalid instruction argument
        Near line: "mulq %rcx          "
        "<null>", line 206 : Invalid instruction argument
        Near line: "    addq %rbx,%rax     "
        "<null>", line 207 : Invalid instruction argument
        Near line: "    adcq [=13=],%rdx   "
CC: ube failed for test.cxx

What does the error message indicate?

很遗憾,不知道。

如果有人买了支持合同,有时间的话,请求Oracle给个答复。

How can I get SunCC to provide a source file and line number?

很遗憾,不知道。

How can I work around the issue?

David Wohlferd 怀疑 [b]"=rm"(b) 输出操作数。看起来一个 ASM 块需要拆分成两个块。这是一个糟糕的 hack,但我们还没有想出另一种方法来做到这一点。

inline word multadd(word a, word b, word* c)
{
    asm(
      "mulq %[b]            \n\t"

      : [a]"+a"(a), [b]"=&d"(b)
      : "0"(a), "1"(b));
    asm(
      "addq %[c],%[a]"      \n\t"
      "adcq [=10=],%[carry]     \n\t"

      : [a]"=a"(a), [carry]"=&d"(*c)
      : "a"(a), "d"(b), [c]"g"(*c) : "cc");

    return a;
}