FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RustでELFファイルを開く方法を調査する (3. Section Headerを読み取る)

Program Headerを読み取ることができるようになったので、次はSection Headerを読み取ることにする。Section Headerに関する情報は、ELFファイルの先頭から、ELFヘッダテーブルにおけるSHOFFバイトの位置から開始している。また、各セクションの大きさは、SH…

RustでELFファイルを開く方法を調査する (2. Program Headerを読み取る)

RustでELFファイルを開く続き。次はProgram Headerを読むコードを書いていく。Program Headerはセグメント領域の情報が格納されている。セグメントにはコードセグメントとデータセグメントが存在し、コードセグメントにはプログラム、データセグメントにはデ…

RustでELFファイルを開く方法を調査する (1. ELFファイルをRustで開く方法)

非常に久しぶりにRustを触っている。RISC-Vシミュレータ以外にもRustでやってみたいことがあって色々調べているのだが、RustでELFファイルなどのバイナリを扱う方法を少し調べていた。シミュレータの用途でもあるし、別の用途でもELFファイルを扱えるといろ…

Circuit IRコンパイラのCIRCTを試す

"CIRCT"は"Circuit IR Compiler and Tools"の略称で、MLIRを用いた回路構成を生成するコンパイラツールである。 https://github.com/llvm/circt ソースコードが構成されており、面白そうなのでダウンロードしてビルドしてみることにした。 まずはソースコー…

QEMUのTCG(Tiny Code Generator)を読み解く(2. TCGが生成したx86機械語を読む)

TCGの続き。TCGによるエンコードをもっと詳しく見るために、最適化を抑制すべくいろいろ変更してみた。 git diff tcg/i386/tcg-target.inc.c diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index ec083bddcf..d86ccdf05b 100644 --- …

QEMUのTCG(Tiny Code Generator)を読み解く

QEMUは高速なエミュレーションが可能な理由の一つに、TCGを使った高速なバイナリ変換機構がある。TCGの役割は、ターゲットバイナリからTCG(Tiny Code Generator)を用いた中間表現に変換し、ホスト形式のバイナリに変換する2つの機構が存在している。 TCGがど…

QEMUに入門してみる(20. CSRレジスタの追加)

QEMU実装の続き。CSR命令の実装が足りていないので、いくつか主要なものを実装していく。現時点ではmhartidしか実装していないので追加していく。csr.cにはCSR命令追加のテンプレートが用意されているのでこれを使っていく。 qemu/target/myriscvx/csr.c /* …

QEMUに入門してみる(19. 分岐命令の実装方法)

QEMU実装の続き。命令実装を進めていく中で、次に実装すべきは分岐命令だ。QEMUで分岐命令をどのように実装するかについて検討を行う。 まずは分岐命令の定義だ。分岐命令はデコードテーブルの中で以下のようにして定義する。 qemu/target/myriscvx/insn32.d…

QEMUに入門してみる(18. ディスアセンブル機能の実装)

前回のQEMUの実行ログを見ると、命令のニーモニックが出力されていなかった。どうしたら命令のディスアセンブルが表示されるんだろう?ということでいろいろ調査した。 IN: Priv: 3; Virt: 0 0x0000000000001000: OBJD-T: 9702000093850202732540f1 このOBJD…

QEMUに入門してみる(17. CSR操作命令が実行される手順の解析)

とりあえずQEMUのブートコードだけ動かしたいので、次はCSR命令を実装しなければならない。RISC-VのCSR命令がQEMUでどのように実行されているかを解析しよう。 まず、CSR命令をinsn32.decodeに追加する。これでCSR命令のデコーダが自動的に追加され、trans_x…

QEMUに入門してみる(16. 命令デコーダの追加)

前回の続き。所望の場所から命令をフェッチできるようになったので、次は命令デコーダを追加していきたい。QEMUにおける命令デコーダはDSLで記述されており、MYRISCVXの場合はqemu/target/myriscvx/insn32.decodeに置いている。これはRISC-Vにおけるデコーダ…

QEMUに入門してみる(15. QEMUにおけるリセットベクタの追加方法)

前回QEMUのトレース情報を取得しながらシミュレーションをスタートできるようになったが、よく見てみると最初の命令でいきなりIllegal Instructionで例外に飛んでいる。当たり前だ、そこに命令は配置されておらず、しかもデコーダもろくに実装していないので…

QEMUに入門してみる(14. トレース関数の自動生成方法)

QEMUにはトレース出力用の関数を自動的に生成するフレームワークが存在している。これは命令トレースを出力するのとは異なり、各種イベントを取得するためのフレームワークを生成するものだ。 まず、取りたいイベントを定義しなければならない。target/myris…

QEMUに入門してみる(13. 割り込み・例外ハンドラの実装)

QEMUのデバッグ続き。次に落ちたのは以下の部分。GDBで確認する。 $ gdb ${QEMU_BUILD}/myriscvx64-softmmu/qemu-system-myriscvx64 Starting program: ${QEMU_BUILD}/myriscvx64-softmmu/qemu-system-myriscvx64 --machine virt --d in_asm --nographic --k…

RISC-V Vector命令をサポートした自作命令セットシミュレータの実装検討 (4. Unit Strideメモリアクセスの実装)

自作命令セットシミュレータのRISC-V Vector Extensionサポート、とりあえずCSR命令の確認が終わったので先に進めていく。 RISC-V Vector Extensionのメモリアクセスにはいくつか種類があって、大きく分けると3種類。 Unit Stride:最もシンプルなメモリアク…

RISC-V Vector Extension v0.9のCSR仕様2

RISC-Vのベクトル拡張の理解に当たり、複雑怪奇なシステムレジスタを理解するのは大変だ。ここではRISC-Vベクトル拡張が備える謎のシステムレジスタについて一気に解説していきたい。 ちなみに最新のRISC-V Vector Extension 0.9をベースに解説している。 RI…

RISC-V Vector Extension v0.9のCSR仕様1

RISC-Vのベクトル拡張の理解に当たり、複雑怪奇なシステムレジスタを理解するのは大変だ。ここではRISC-Vベクトル拡張が備える謎のシステムレジスタについて一気に解説していきたい。 ちなみに最新のRISC-V Vector Extension 0.9をベースに解説している。 RI…

LLVMの新しい中間言語表現 MLIRを試す(6. MLIRに関する発表資料を読む)

MLIRについてもう少し具体的な例を勉強するために、資料を読み込んでいくことにした。前回の続き。 以下の資料を参考にした。Chris Lattnerの所属がSiFiveに変わっているので、比較的最近の資料だ。 docs.google.com MLIRとLLVM IR MLIRをLLVM IRの代替とし…

LLVMの新しい中間言語表現 MLIRを試す(5. MLIRに関する発表資料を読む)

MLIRについてもう少し具体的な例を勉強するために、資料を読み込んでいくことにした。前回の続き。 以下の資料を参考にした。Chris Lattnerの所属がSiFiveに変わっているので、比較的最近の資料だ。 docs.google.com MLIRをClangで使用する 現在のClangのIR…

LLVMの新しい中間言語表現 MLIRを試す(5. MLIRに関する発表資料を読む)

MLIRについてもう少し具体的な例を勉強するために、資料を読み込んでいくことにした。前回の続き。 以下の資料を参考にした。Chris Lattnerの所属がSiFiveに変わっているので、比較的最近の資料だ。 docs.google.com 次はTensorFlowのExampleの例を見る。Ten…

LLVMの新しい中間言語表現 MLIRを試す(4. MLIRに関する発表資料を読む)

MLIRについてもう少し具体的な例を勉強するために、資料を読み込んでいくことにした。前回の続き。 以下の資料を参考にした。Chris Lattnerの所属がSiFiveに変わっているので、比較的最近の資料だ。 docs.google.com MLIR Infrastructureについて この"Batte…

LLVMの新しい中間言語表現 MLIRを試す(3. MLIRに関する発表資料を読む)

MLIRについてもう少し具体的な例を勉強するために、資料を読み込んでいくことにした。 以下の資料を参考にした。Chris Lattnerの所属がSiFiveに変わっているので、比較的最近の資料だ。 docs.google.com MLIRはMulti-Level Intermediate Representation Comp…

QEMUに入門してみる(12. QEMUでのコールバック関数追加方法の調査)

QEMUの続き。QEMUのRISC-V対応においてバイナリのシミュレーション方法とログの出し方が分かったわけだが、これをMYRISCVXに移植したい。つまり同じコマンドをqemu-system-myriscvx64に適用することを考える。 まずは変換のための初期化関数から。 qemu/targ…

QEMUに入門してみる(11. QEMUでのコールバック関数追加方法の調査)

QEMUの続き。QEMUのRISC-V対応においてバイナリのシミュレーション方法とログの出し方が分かったわけだが、これをMYRISCVXに移植したい。つまり同じコマンドをqemu-system-myriscvx64に適用することを考える。 ./qemu-system-myriscvx64 --machine none --d …

QEMUに入門してみる(10. QEMUでのベアメタルバイナリの実行方法調査)

QEMUの続き。前回、QEMUを使ってLinux向けにコンパイルされたバイナリを実行することができるようになったが、ベアメタルのバイナリを動かすことはまだできていない。目標としてはとりあえずriscv-tests関係のプログラムを動かすことができるようになりたい…

QEMUに入門してみる(9. QEMUでの詳細トレースの出し方)

QEMUの続き。QEMUを使ってRISC-Vのアプリケーションやベンチマークを走らせたい。とりあえずは普通のRISC-Vのバイナリで動作を確認するところから始めよう。 main.c #include <stdio.h> int main() { printf("Hello World\n"); return 0; } $ riscv64-unknown-linux-g</stdio.h>…

QEMUに入門してみる(8. translateに必要な関数の確認)

QEMUの続き。独自ターゲットでビルドしてみる。前回の続き。 gen_load()とgen_store()で使用されている関数を定義しなければならない。 gen_get_gpr():GPRから値を取得する関数。 /* Wrapper for getting reg values - need to check of reg is zero since …

QEMUに入門してみる(7. translateに必要な関数の確認)

QEMUの続き。独自ターゲットでビルドしてみる。前回の続き。 QEMUのデコーダを作っていく。QEMUのデコーダはDSLを使って記述するらしい。translate.cで呼び出されているecode_insn32()を作っていく。 qemu/target/myriscvx/translate.c static void decode_o…

QEMUに入門してみる(6. translateに必要な関数の確認)

QEMUの続き。独自ターゲットでビルドしてみる。前回の続き trans_xxx()の関数がみんな消えてしまったのはおそらく最適化で消されたので、一応念のためDebugビルドしてオブジェクトをダンプしてみた。 $ ../configure --enable-debug --disable-pie --target-…

QEMUに入門してみる(5. translateに必要な関数の確認)

QEMUの続き。独自ターゲットでビルドしてみる。static const TranslatorOps myriscvx_tr_opsで必要な関数を調査する。 必要な関数を確認しながら追加していく。myriscvx_tr_breakpoint_check()の中で、デバッグ例外を発生させることが必要だ。 static bool m…