個人的な学習メモです。
Calling Conventions1
関数やcall、invokeは呼び出しにあたってオプショナルの呼び出し規約(calling convension)を指定することができる。ダイナミックなcaller/calleeのペアは呼び出し規約が一致していなければならない。
呼び出し規約1
- ccc
Cの呼び出し規約。他の呼び出し規約が指定されていない場合のデフォルト値。ターゲットのCの呼び出し規約を指定する。 - fastcc
可能な限り高速な呼び出しを行う規約。例としてはレジスタでの値受け渡しなど。この規約は外部で指定されたABI(アプリケーションバイナリインタフェース)に従わず、高速なコードを生成するために任意の手段を取ることができる。 - caldcc
この規約は、通常は呼び出しが行われないことを前提として、callerのコードを可能な限り効率化しようとするもの。呼び出しによってcallerのレジスタライブレンジを壊さないように、すべてのレジスタを保持しておくことが多い。また、この規約の関数はインライン化の対象にならない。 - ghccc
Glasgow Haskellコンパイラ(GHC)で使用される特殊な規約。 - cc ll
EricssonのHiPEコンパイラで使用される特殊な規約。 - anyregcc
callerに任意のコードをパッチングすることをサポートしている特殊な規約。呼び出し引数を強制的にレジスタに格納するが、それらは動的に割り当てられる。現在のところ、llvm.experimental.patchpointの呼び出しでのみ使用できる。 - preserve_mostcc
できる限りcallerのコードには影響を与えないようにする規約。引数と戻り値の渡し方はCの呼び出し規約と同じように動作するが、caller/callee-savedレジスタは異なる。これは呼び出し前後で多数のレジスタセットを保存、回復する負荷を低減するためである。また、引数がcallee-savedレジスタに渡されるときは、それらは呼び出しの間、calleeによって保持される。保持されている値はcallee-savedレジスタには反映されない。 - preserve_allcc
preserve_mostccよりもさらに、callerのコードに影響を与えないようにする規約。 - preserve_nonecc
この規約では呼び出しにあたって汎用レジスタは保存されない。つまり、すべての汎用レジスタはcallerが保存する。またすべての汎用レジスタを引数の受け渡しに使用する。 - cxx_fast_tlscc
Clangはc++スタイルのTLSへのアクセス関数を生成する。このアクセス関数は一般的に、入口ブロック、出口ブロック、初期化ブロックを持つ。この規約は、可能な限り多くのレジスタ(エントリーブロックとエグジットブロックで構成されるファストパスで保持されるすべてのレジスタ)を保持することで、呼び出し側のオーバーヘッドを最小限に抑えることを目的としている。 - tailcc
この規約は、tailポジションの呼び出しが、常に最適化されることを保証する。可能な限りtail callを生成すること以外はfastccと同等である。 - swiftcc, swifttailcc
Swift言語で使われる規約。 - cfguard_checkcc
コントロールフローガードチェック関数で使われる。このチェック関数は間接呼び出し(インダイレクトコール)の前に挿入され、calleeが有効な関数アドレスであることをチェックする関数。 - cc
任意の呼び出し規約を番号で指定する形式。ターゲット固有の規約を使用できる。
この他にもターゲットに依存しない規約をサポートするために、必要に応じて規約を追加・定義することができる。