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

时间:2017-01-25 13:13:26

标签: c++ solaris sunstudio suncc

我在Solaris 11.3上使用Developer Studio 12.5附带的SunCC编译器构建Botan。我对库或Solaris不太熟悉,我需要花一些时间来追踪问题。

编译在一个名为divide.cpp的相对温和的文件上死亡。我已将其缩减为以下测试用例。根据甲骨文的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 $0,%[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有缺陷并购买支持合同以了解更多信息。

我有三个问题:

  • 错误消息表示什么?

  • 如何让SunCC提供源文件和行号?

  • 如何解决此问题?

如果我将 b 参数更改为 =m ,那么产生同样的错误。如果我将 b 参数更改为 =r ,则会出现其他错误生成:

asm(
    "mulq %[b]          \n\t"
    "addq %[c],%[a]     \n\t"
    "adcq $0,%[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 $0,%rdx   "
CC: ube failed for test.cxx

1 个答案:

答案 0 :(得分:1)

  

错误消息表示什么?

不幸的是,不知道。

如果有人购买了支持合同并且有时间,那么请征求Oracle的回答。

  

如何让SunCC提供源文件和行号?

不幸的是,不知道。

  

我如何解决这个问题?

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

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 $0,%[carry]     \n\t"

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

    return a;
}