以下代码使用内联汇编填充结果:
uint64_t Foo::f() {
uint64_t result;
asm volatile
("vldmia %1, {q0-q1} \n" // q0-1 = *this
⋮
"vstmia %0, {d0} \n" // result = d0
:: "r"(&result), "r"(this)
: "q0", "q1");
return result;
}
result
变量在汇编代码中无条件设置,但Xcode的分析器似乎忽略了这一点(流分析直接从声明跳到return语句)并抱怨:
…/BitBoard.cpp:26:9: Undefined or garbage value returned to caller
有没有办法安抚分析器而不浪费周期初始化result
?
编辑:我已尝试过建议来指定输出约束:
: "=r"(&result) : "r"(this), "r"(&result)
但编译器在asm输出"中使用"无效左值。删除&
编译但返回看似随机的结果。将vstmia %0, {d0}
更改为vmov %0, d0
也会失败,其中"指令的操作数无效"。
我怀疑我必须按照建议将result
标记为输出,并在汇编代码中以不同方式填充它,但我无法找到有关知道的任何信息。
答案 0 :(得分:2)
我怀疑这是由于缺少输出约束。
试试这个,
uint64_t Foo::f() {
uint64_t result;
asm /* volatile */
("vldmia %1, {q0-q1} \n" // q0-1 = *this
⋮
"vstmia %0, {d0} \n" // result = d0
: "=w"(result): "r"(this) : "q0", "q1");
return result;
}
您必须使用输出约束"=w"(result)
来告诉编译器汇编程序正在设置值。如果你这样做,你可能不需要volatile
。至少,这是一个很好的消除问题。
答案 1 :(得分:0)
我找到了解决办法,但我仍然希望找到更优雅的解决方案:
union {
uint64_t result;
struct { uint32_t a, b; };
};
asm
("vldmia %2, {q0-q1} \n" // q0-1 = *this
⋮
"vmov %0, s0 \n"
"vmov %1, s1 \n"
: "=r"(a), "=r"(b) : "r"(this)
: "q0", "q1");
return result;