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 のアナライザーはこれを無視しているようで (フロー分析は宣言から return ステートメントまで直接スキップします)、次のように文句を言います。

…/BitBoard.cpp:26:9: Undefined or garbage value returned to caller

初期化サイクルを無駄にすることなく、Analyzer を鎮圧する方法はあります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 に答える