我们在默认配置中使用Clang。在默认配置中,使用Clang的Integrated Assembler(而不是系统汇编程序,如GAS)。我无法确定确切的问题(并修复):
make
...
clang++ -DNDEBUG -g2 -O3 -Wall -fPIC -arch i386 -arch x86_64 -pipe -Wno-tautological-compare -c integer.cpp
integer.cpp:542:2: error: unknown token in expression
AS1( neg %1)
^
./cpu.h:220:17: note: expanded from macro 'AS1'
#define AS1(x) GNU_AS1(x)
^
./cpu.h:215:24: note: expanded from macro 'GNU_AS1'
#define GNU_AS1(x) "\n\t" #x ";"
^
<inline asm>:3:6: note: instantiated into assembly here
neg %rcx;
^
有问题的代码如下。
我 认为 上述错误可能与Inline Assembly and Compatibility有关。一个简单的negq %1
没有按预期工作:
integer.cpp:543:2: error: unknown token in expression
AS1( negq %1)
^
./cpu.h:220:17: note: expanded from macro 'AS1'
#define AS1(x) GNU_AS1(x)
^
./cpu.h:215:24: note: expanded from macro 'GNU_AS1'
#define GNU_AS1(x) "\n\t" #x ";"
^
<inline asm>:3:7: note: instantiated into assembly here
negq %rcx;
^
自英特尔大会以来,我也试过了negq [%1]
,neg DWORD PTR [%1]
和negq DWORD PTR [%1]
。
“表达式中的未知令牌”似乎是一个虚假的消息,因为它抱怨的汇编指令似乎没有问题。所以我怀疑Clang集成装配器还有其他东西让人反感。
代码有什么问题?
导致编译错误的代码:
int Baseline_Add(size_t N, word *C, const word *A, const word *B)
{
word result;
__asm__ __volatile__
(
".intel_syntax;" "\n"
AS1( neg %1)
ASJ( jz, 1, f)
AS2( mov %0,[%3+8*%1])
AS2( add %0,[%4+8*%1])
AS2( mov [%2+8*%1],%0)
ASL(0)
AS2( mov %0,[%3+8*%1+8])
AS2( adc %0,[%4+8*%1+8])
AS2( mov [%2+8*%1+8],%0)
AS2( lea %1,[%1+2])
ASJ( jrcxz, 1, f)
AS2( mov %0,[%3+8*%1])
AS2( adc %0,[%4+8*%1])
AS2( mov [%2+8*%1],%0)
ASJ( jmp, 0, b)
ASL(1)
AS2( mov %0, 0)
AS2( adc %0, %0)
".att_syntax;" "\n"
: "=&r" (result), "+c" (N)
: "r" (C+N), "r" (A+N), "r" (B+N)
: "memory", "cc"
);
return (int)result;
}
答案 0 :(得分:0)
这似乎是Integrated Assembler中的一个问题。在CFE-dev邮件列表上提出问题后,其中一位LLVM开发人员开设了PR。另请参阅LLVM Bug 24232 - [X86] Inline assembly operands don't work with .intel_syntax。
我认为这意味着如果我们有时间和精力用1000行重写块,迈克尔的评论可能是一个解决方案。