Я строю Ботан в Solaris 11.3 с компилятором SunCC, который поставляется с Developer Studio 12.5. Я не слишком знаком с библиотекой или с Solaris, и мне требуются некоторые усилия, чтобы отследить проблемы.
Компиляция умирает на относительно мягком файле под названием divide.cpp
. Я сократил его до следующего теста. Согласно Oracle Поддержка встроенного ассемблера в стиле GCC в компиляторах Sun Studio 12, 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
. я нашел SunCC душит встроенный ассемблер на платах Oracle. Но ответ — 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
Что означает сообщение об ошибке?
К сожалению, не знаю.
Если кто-то покупает контракт на поддержку и у него есть время, попросите Oracle получить ответ.
Как я могу заставить SunCC предоставить исходный файл и номер строки?
К сожалению, не знаю.
Как я могу обойти эту проблему?
Дэвид Волферд подозревал [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;
}
Других решений пока нет …