2

積分を計算する AT&T アセンブリ関数を作成しました。C で記述されたコードによって呼び出されるため、戻り値として渡す必要があります。単精度floatおよび倍精度として正常に返すことができましたdouble。しかし、80 ビットの拡張倍精度で計算できることはわかっているので、それを C に渡したいと思っています。

渡したい値が、TOP が指す FPU レジスタで指されていると仮定しましょう。関数を呼び出す方法は次のとおりです。

フロートの場合:

//C
double  integ_fo=integ_asm_fpu_fl();

#asm
...  
fstps   max        # Fpu STore and Pop Short <- short for 32-bit
movss   max, %xmm0 # MOVe Scalar Single precision   

ダブルの場合:

//C
double  integ_do=integ_asm_fpu_do();

#asm
...  
fstpl   max        # Fpu STore and Pop Long <- long for 64-bit
movsd   max, %xmm0 # MOVe Scalar Dingle precision 

私の質問は次のとおりです。Cがレジスタ long doubleから読み取れるように、次のコードをどのように完成させることができますか。%XMM0

ロングダブルの場合:

//C
long double  integ_lo=integ_asm_fpu_lo();

#asm
...  
fstpt   max        # FPU Store and Pop exTended <- extended for 80-bit

その後どうすればいいですか?maxからに80 ビットを移動するにはどうすればよい%XMM0ですか?

4

1 に答える 1

4

あなたの前提は間違っています:

C が %XMM0 レジスタから long double を読み取ることができるように、次のコードを完成させるにはどうすればよいですか。

long doublesysv abiはxmm0レジスタに戻りませんが、 st0. ドキュメントの関連部分:

long double 型の引数の 64 ビットの仮数はクラス X87 に属し、16 ビットの指数に 6 バイトのパディングを加えたものはクラス X87UP に属します。

クラスが X87UP の場合、値は以前の X87 値と共に %st0 に返されます。

どうやらすでに値が入っているst0ので、そのままにしておく必要はありません。つまりfstpt、例の を削除します。

于 2016-05-04T16:01:48.893 に答える