(Microsoft)x64呼び出し規約は次のように述べています。
引数は、レジスタRCX、RDX、R8、およびR9で渡されます。引数がfloat/doubleの場合、XMM0L、XMM1L、XMM2L、およびXMM3Lで渡されます。
それは素晴らしいことですが、なぜただフロート/ダブルするのですか?整数(およびおそらくポインター)もXMMレジスターを介して渡されないのはなぜですか?
利用可能なスペースの無駄のように思えますね。
非FP値(つまり整数とアドレス)に対するほとんどの操作は、汎用レジスタを使用するように設計されているためです。
整数のSSE演算がありますが、それらは算術のみです。
したがって、呼び出し規約がSSEレジスタを介した整数とアドレスの受け渡しをサポートしている場合、ほとんどの場合、値を汎用レジスタにコピーする必要があります。
関数は、多くの場合、ポインター(インデックスとして、またはループ境界としてエンドポインターを計算するため)、またはGPレジスター内の他の整数引数で整数引数を使用する必要があります。または、GPレジスタで処理したい他の整数をメモリからロードします
XMM reg内の整数をループカウンターまたはバインドとして効率的に使用することはできません。これは、分岐命令の整数フラグを設定するパックされた整数の比較がないためです。(pcmpgtd
0 / -1要素のマスクを作成します)。
XMMベクトルレジスタに関数パラメータを格納しないのはなぜですか?も参照してください 。詳細については、他の回答をご覧ください。
しかし、それを超えても、この設計アイデアはWindows x64 fastcall/vectorcallのオプションではありません。
Windows x64は、可変個引数関数を単純化するために意図的にスペースを浪費することを選択します。レジスタ引数は、戻りアドレスの上の32バイトの「シャドウスペース」/「ホームスペース」にダンプして、引数の配列を形成できます。
これが、(たとえば)Windows x64が、以前の引数のタイプに関係なく、R8またはXMM2の3番目の引数を渡す理由です。また、可変個引数関数の呼び出しでFP引数も対応する整数レジスタにコピーする必要があるので、関数プロローグは、どの可変個引数引数がFPで、どれが整数であるかを特定せずに、引数regをダンプできます。
arg-arrayを機能させるために、整数引数とFP引数が混在しているかどうかに関係なく、レジスタに渡すことができるのは合計4つの引数のみです。 すべて整数であっても、レジスタ引数の最大数をすでに保持するのに十分なGP整数レジスタがあります。
(x86-64 System Vとは異なり、使用される整数/ポインターarg-passingレジスターの数に関係なく、最初の最大8つのFP引数がxmm0..7で渡されます。)