0

gcc に asm インラインの内部使用のみにレジスタを割り当てるように依頼する方法はありますか? 以下は、r5 が asm で直接使用される (疑似 asm の) 例ですが、これは任意の汎用レジスタである可能性があり、内部でのみ使用されるため、入力でも出力でもありません。

asm("load_immediate_value %%r5,0;"
    /* ... */
    "add_immediate_value %%r5,%%r5,42"
    /* ... */
    :
    :
    : "r5");

この例では、レジスタ r5 を選択し、それを使用していることを clobber リストを通じて gcc に伝えます。しかし、r5 が ABI レジスタの場合はどうなるでしょうか?! 自分で名前を付けなくても、簡単にレジスターを要求する方法が必要です。

4

1 に答える 1

0

これが通常行われる方法は次のとおりです。

static __inline__ void set_archctrl0(unsigned long val) {
    register unsigned long archctrl0 __asm__("archctrl0") = val;

    __asm__ __volatile__("" : "+r"(archctrl0) : : "cc", "memory");
}

asmステートメントは、コンパイラが全体を最適化しないようにするためだけに存在します。

または、より実用的な例として、スタックポインタ レジスタの読み取りは次のように実行できます。

static __inline__ void * getSP(void) {
    register void * sp asm("sp");
    asm ("" : "=r"(sp));
    return sp;
}

変数を特定のレジスタにバインドする方法は、GCC マニュアルのExplicit Register Variablesセクションに記載されています。

もちろん、アーキテクチャ固有のレジスタの書き込みにカスタム命令が必要な場合 (つまり、レジスタ値を初期化するために CPU が通常使用する「移動」または「ロード」のタイプを使用して実行できない場合)、次のようなものが必要になります。

static __inline__ void set_archctrl0(unsigned long val) {
    __asm__ __volatile__("setarchctrl0 %0" : : "r"(val) : "cc", "memory");
}

明らかに、これらはすべて「通常の」コードで使用されていないレジスタに対してのみ機能します (つまり、プラットフォーム ABI の外部/グローバルとしてプラットフォーム ABI によって明示的に予約されている/コンパイルされたコードによって触れられないレジスタとして)。

この方法で「汎用レジスターから手を離す」ようにコンパイラーに指示することはできません。私の知る限り、それは gcc では不可能です。

于 2013-04-19T09:00:33.920 に答える