clang / gcc :一些内联汇编操作数可以满足多个约束,例如, "rm"
,当操作数可以满足寄存器或存储器位置时。例如,64 x 64 = 128位乘法:
__asm__ ("mulq %q3" : "=a" (rl), "=d" (rh) : "%0" (x), "rm" (y) : "cc")
生成的代码似乎为参数选择内存约束 3
如果我们注册饥饿,这将是好的,以避免泄漏。显然,x86-64的注册压力要小于IA32。但是,生成的程序集片段(由 铛)是:
movq %rcx, -8(%rbp)
## InlineAsm Start
mulq -8(%rbp)
## InlineAsm End
选择内存约束显然毫无意义!将约束更改为: "r" (y)
但是(强制注册)我们得到:
## InlineAsm Start
mulq %rcx
## InlineAsm End
正如所料。这些结果适用于clang / LLVM 3.2(当前Xcode版本)。第一个问题: 为什么clang会在这种情况下选择效率较低的约束?
其次,使用较少,逗号分隔, 多种替代约束 句法:
"r,m" (y)
, 哪一个 应该 评估每种替代方案的成本,并选择导致复制较少的方法。这似乎工作, 但是铿锵只选择了第一个 - 如下所示: "m,r" (y)
我可以简单地放弃 "m"
替代约束,但这并不表示可能的合法操作数的范围。这让我想到第二个问题: 这些问题是否已在3.3中得到解决或至少得到承认? 我试过查看LLVM开发档案,但我宁愿在不必要地进一步限制约束或加入项目讨论等之前征求一些答案。