これが通常行われる方法は次のとおりです。
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 では不可能です。