13

私は LLVM で書かれたコンパイラを持っており、ABI 準拠を目指しています。たとえば、Windows x86 または Linux での C ABI の仕様ドキュメントを実際に見つけるのは難しいと感じました。そして、私が見つけたものは、私が使用できる IR 用語ではなく、RAX/EAX/etc の観点から説明しています。

これまでのところ、LLVM は集合体を目に見えないように扱っている、つまり、集合体のメンバーをそれぞれ別個のパラメーターと見なしていると考えてきたと思います。たとえば、Windows x64 では、ドキュメントにあるように集計を処理したい場合、8、16、32、または 64 ビットの場合、そのサイズの単一の整数に強制する必要があります。それ以外の場合は、ポインターで渡します。

Windows x86 の場合、すべてのパラメーターがスタックに渡されるため、__cdecl と __stdcall は私からのアクションを必要としないようです。__fastcall によると、最初の 2 つの 32 ビット以下の引数はレジスターで渡されるため、そのサイズ以下の集約を強制する必要があります。__thiscall はこれをレジスタに渡し、残りはスタックに渡すので、ここで調整を行う必要はないようです。

__vectorcall の場合、整数型強制により sizeof(void*) 以下の集合体を渡します。その他の集計については、それらが HVA の場合は値で渡します。それ以外の場合は、x86 では値渡し、x64 ではポインター渡しです。

これは (まあ、比較的) 単純に思えますが、LLVM のドキュメントにはsext明確に記載されています。呼び出し元 (パラメーターの場合) または呼び出し先 (戻り値の場合) によって。". x86 呼び出し規則に関する Microsoft のページでは、任意の幅に何かを拡張することについては何も言及されていません。

byvalまた、Windows で属性を生成する Clang によって生成された LLVM IR を観察しました。上記から得た理解では、byvalの使用は必要ありません。

さまざまなプラットフォーム C ABI を LLVM IR に下げるにはどうすればよいですか?

4

2 に答える 2

6

あなたの質問を 100% 理解しているとは言えませんが、LLVM IR はプラットフォーム ABI のすべての機微を単純に表すことができないことに注意してください。したがって、Clang ツールチェーンでは、オブジェクトを値で関数に適切に渡すなど、ABI の低下を実行するのはフロントエンドです。

lib/Basic/Targets.cpp定義については、Clang ソース ツリーを参照してください。悲惨な詳細はさらにlib/CodeGen/TargetInfo.cpp

于 2014-08-05T17:19:01.360 に答える