シミュレータを使用して、既存のアーキテクチャ (x86) でいくつかのアーキテクチャの変更をテストしたいと考えています。ただし、それらを適切にテストしてベンチマークを実行するには、命令セットにいくつかの変更を加える必要がある場合があります。これらの変更を GCC または他のコンパイラに追加する方法はありますか?
3 に答える
簡単な解決策:
一般的なアプローチの 1 つは、インライン アセンブリを追加し、命令バイトを直接エンコードすることです。
例えば:
int main()
{
asm __volatile__ (".byte 0x90\n");
return 0;
}
(gcc -O3) をコンパイルすると、次のようになります。
00000000004005a0 <main>:
4005a0: 90 nop
4005a1: 31 c0 xor %eax,%eax
4005a3: c3 retq
したがって、0x90 を inst バイトに置き換えるだけです。もちろん、通常の objdump で実際の命令を確認することはできず、プログラムは (nop の組み合わせのいずれかを使用しない限り) システムで実行されない可能性がありますが、シミュレーターは適切に実装されていればそれを認識するはずです。
コンパイラがこの命令を認識していない場合、コンパイラが適切に最適化することは期待できないことに注意してください。正確さを保証します。最適化は、必要な場合にのみ使用してください。
複雑なソリューション
別のアプローチは、これをコンパイラに実装することです-gccで実行できますが、コメントに記載されているように、LLVMはコンパイラ開発プラットフォームとして設計されているため、おそらく使用するのに最適なものの1つですが、それでも非常に複雑ですLLVM は IR の最適化ステージに最適であり、ターゲット固有のバックエンドを変更しようとする場合はやや使いにくいためです。
それでも、実行可能であり、この命令をいつ発行するかをコンパイラーに決定させる予定がある場合は、それを行う必要があります。ただし、最初のオプションから開始して、シミュレーターがこの追加で機能するかどうかを確認し、その後コンパイラー側で時間を費やすことをお勧めします。
これを LLVM に実装することを決定した場合、最善の策はそれを組み込み関数として定義することです。これに関する比較的多くのドキュメントがここにあります - http://llvm.org/docs/ExtendingLLVM.html
それは実行可能であり、私はそれを実行しましたが、面倒です。これは基本的に、既存のプラットフォームをモデルとして使用して、コンパイラを新しいプラットフォームに移植するプロセスです。GCC のどこかに命令セットを定義するファイルがあり、コンパイル中にさらにコードとデータを生成するさまざまなプロセスを経ます。20年以上前なので細かいところは忘れてしまいました、すみません。