1

以下代码使用内联汇编填充结果:

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 的 Analyzer 似乎忽略了这一点(流分析直接从声明跳到 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按照建议将其标记为输出,并在汇编代码中以不同方式填充它,但我找不到任何关于知道这样做的信息。

4

2 回答 2

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如果你这样做,你可能不需要。至少,这是一个很好的消除问题。

于 2013-06-15T02:21:30.053 回答
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;
于 2013-06-15T06:05:48.463 回答