[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
スタック状のレジスタを asm のオペランドで使うには幾つか規則がある。 これらの規則は、スタック状レジスタであるオペランドにのみ適用される。
asm_operands
中で死ぬ入力レジスタの組が与えられた場合、
どれが asm 文により暗黙にポップされて、どれが GCC で明示的に
ポップしなければならないかを知る必要がある。
asm 文により暗黙にポップされる入力kレジスタは、出力オペランドに マッチするように制約が課されていない限り、明示的に破壊しなければ ならない。
暗黙にポップされる入力レジスタは全て、暗黙にポップされないどの入力 レジスタよりもレジスタスタックの最上に近くなければならないのである。
ある入力が insn の中で死ぬのであれば、再ロードでその入力レジスタを 出力再ロード用に使っても良い。次の例を考えてみよう。
asm ("foo" : "=t" (a) : "f" (b)); |
この asm 文は、入力 B が asm によりポップされないこと、asm が結果を レジスタ・スタックにプッシュする、すなわち、スタックが前より一段 深くなるということを言っている。しかし、入力 B がこの insn で 死ぬのであれば、再ロードは、入力と出力に同じレジスタを使うことが 出来ると考えるだろう。
入力オペランドのどれかが制約 f
を使っていれば、
全ての出力レジスタの制約は早期破壊 &
を使用しなければならない。
上の asm は以下のように書ける。
asm ("foo" : "=&t" (a) : "f" (b)); |
出力オペランドは、asm の後で出力がどのレジスタに現れるかを
はっきりと指示しなければならない。=f
は許されない。
このオペランド制約は一個のレジスタからなるクラスを選択しなければならない。
asm_operands
の前で死んでおり、
asm_operands
によりプッシュされる。
レジスタスタックの一番上以外の場所にプッシュするのは意味がない。
出力オペランドはレジスタスタックの一番上から始まっていなければ ならない。出力オペランドはレジスタを「スキップ」してはいけない。
以下に、書くのが妥当と思われる asm 文を2,3示す。 次の asm 文は入力を一つ取り、この入力は内部的にポップされる。 そして、出力を二つ生成する。
asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp)); |
次の asm 文は、二つの入力を取る。これらは、オペコード fyl2xp1
に
よりポップされ、一つの出力に置き換えられる。
ユーザは、reg-stack.c が fyl2xpl
が両方の入力をポップするという
ことが判るように破壊指定 st(1)
を書かなければならない。
asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)"); |
This document was generated
using texi2html 1.78.