FPGA開発日記

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

2019-10-01から1ヶ月間の記事一覧

オープンソースRISC-VコアHummingBirdについて調査(1. ダウンロードとビルド)

RISC-Vの実装であるHummingBirdを調査していくことにした。 HummingBirdの概要 HummingBirdは中国の大学で開発されたRISC-Vコアで、正式にはE203という名前が付けられている。GitHubのページを参照すると、このHummingBirdを開発した目的はRISC-Vの人気を向…

オリジナルLLVMバックエンド実装をまとめる(30. llvm-litによるテストの追加)

前回の続き。MYRISCVXのテストを追加する。 simple_main.cppをclangでコンパイルすると、以下のようなLLVM中間コードが生成される。 ./bin/clang --target=riscv64-unknown-elf -c ../myriscvx-tests/tests/simple_main.cpp -emit-llvm -o - | ./bin/llvm-di…

オリジナルLLVMバックエンド実装をまとめる(29. llvm-litによるテストの調査)

LLVMのオリジナルのバックエンドを実装してきたが、いろんなソースコードをコンパイルして、いろんなテストプログラムを動かしてきた。 これだけ多くのテストパタンを実行するのなら、テスト環境とリグレッションテストを用意しておくのが良い。LLVMは、テス…

複数のGitHubアカウントに対して複数のSSHキーを設定するための方法

人によってはGitHubのアカウントを2つ以上持っていたり、社内で複数のGitHubアカウントを使い分ける必要があったりする場合がある。 例えば仕事用と趣味用でGitHubアカウントを2つ用意していたり、その場合は1つのPCから複数のGitHubに対して制御を行う必要…

オリジナルLLVMバックエンド実装をまとめる(28. llvm-objdumpを実装する2)

前回の続き。命令ダンプのオペランド表記を一部改造する このままでLLVMをコンパイルして実行しても良いのだが、例えば以下のような命令はダンプの結果がおかしくなる。 addi x2, x2, -4 --> addi x2, x2, 4092 マイナス値の表記がうまく行えない。オペラン…

オリジナルLLVMバックエンド実装をまとめる(27. llvm-objdumpを実装する1)

ELFファイルの生成とディスアセンブラの作成 LLVMには、ツールセットとして生成したオブジェクトファイルを逆アセンブルするためのllvm-ojbdumpというコマンドが用意されている。 基本的に生成したオブジェクトファイルはこのコマンドを用いてダンプすること…

CQ出版 インタフェース 12月号「注目オープンソースRISC-Vマイコン」に寄稿しました

CQ出版さんが出版している雑誌インタフェースの12月号で、「注目オープンソースRISC-Vマイコン」という特集記事に寄稿しました。 RISC-Vマイコンの話がメインなんですが、よく見ると私はマイコンの話はほとんど書いていないですね。 なんか仕様だのクラウド…

オリジナルLLVMバックエンド実装をまとめる(26. LLVM IRをサポートするためのIntrinsicsのサポート2. )

前回の続き。 データのバイトスワップを行う。C言語では、__builtin_bswap16, __builtin_bswap32, __builtin_bswap64により取得することができる。 これらはそのまま命令に落とし込めないので、IRの生成を抑制する。 func_bswap.cpp int test_bswap16() { vo…

ハードウェアの構築からチップ設計までを一気通貫するフレームワークChipyardを試す(1. 環境構築とシミュレーション)

ChipyardというのはRISC-Vをベースとしたチップ設計のためのフレームワークで、ツールセット・ライブラリ・デザインなどを一つにまとめたフレームワークのようだ。このフレームワークを使用することで、ハードウェアの設計からシミュレーション・論理合成・…

「実践Rust入門」に入門している

少し前から、「実践Rust入門」を読み始めている。Rust自体は前に触ったことがあるのだが、ジェネリクスとかトレイトとか、基本的な知識が不足しているので、評判が良さそうな本を購入して読み進めていくことにした。 実践Rust入門[言語仕様から開発手法まで]…

中国語版RISC-Vの入門書を買ってみた

RISC-Vの入門書といえば、RISC-V Readerなど基本的に英語のものが日本語に翻訳されるという形式が多いが、中国語版の良さそうなものがあったので無理やり買ってみた。 2冊セットで、結構分厚い。漢字ばっかりで、眩暈がしてくるぞ。。。 とりあえず、スマホ…

オリジナルLLVMバックエンド実装をまとめる(25. LLVM IRをサポートするためのIntrinsicsのサポート)

LLVM IRには、いくつかの特殊な構文が存在し、これらをサポートすることでより多くのコードを生成できるようになる。 これらについては、clang側からIntrinsic関数を呼び出すことでLLVM IRを生成し、llcに渡してテストすることができる。 frame_addres, retu…

オリジナルLLVMバックエンド実装をまとめる(24. 末尾再帰関数呼び出しの実装2.)

前回の続き。末尾再帰の生成について。 LowerCallに戻る。IsTailCallがTrueとなり、末尾関数呼び出し最適化が有効として読み進める。 ... if (!IsTailCall) Chain = DAG.getCALLSEQ_START(Chain, NextStackOffset, 0, DL); ... 末尾関数呼び出し最適化が有効…

オリジナルLLVMバックエンド実装をまとめる(23. 末尾再帰関数呼び出しの実装1.)

関数呼び出しには様々な最適化の形があるが、その中の一つである末尾関数呼び出しでの最適化を実行してみる。 末尾関数呼び出しとは、ある関数f1()が関数f2()の最後の処理として呼び出されるケースを言う。 int f1(a, b) { a + b; } int f2(c, d, e, f) { /*…

オリジナルLLVMバックエンド実装をまとめる(22. 可変長引数をサポートするための処理)

C言語の可変長引数では、例えば以下のような記述が可能となる。 vararg.cpp #include <stdarg.h> int sum_i(int amount, ...) { int i = 0; int val = 0; int sum = 0; va_list vl; va_start(vl, amount); for (i = 0; i < amount; i++) { val = va_arg(vl, int); sum </stdarg.h>…

オリジナルLLVMバックエンド実装をまとめる(21. ByVal属性のついた引数を扱うための処理2)

前回の続き。 ByVal属性の引数における呼び出し側の処理 それでは、次に呼び出し側はどのようになっているのだろうか。 呼び出し側でも、ByVal属性のついた引数を一つ一つコピーして関数呼び出され側に渡す必要がある。 関数呼び出し側は、MYRISCVXTargetLow…

オリジナルLLVMバックエンド実装をまとめる(20. ByVal属性のついた引数を扱うための処理)

今までの関数処理の中で、引数は基本的にポインタか値渡し、そして値も何らかの型の値を1つずつ渡していくという形式だった。 しかし、C言語では構造体などの複数の要素をまとめた型を渡すことができる。また、C言語では構造体の値をそのまま値渡しで引数と…

オリジナルLLVMバックエンド実装をまとめる(19. LLVM IRからInstruction Selectionまでの流れ2)

前回の続き。 Legalizeでは、ターゲット固有のノードへの変換を行う。LLVM IRでは様々な演算ノードを定義しているが、ターゲットアーキテクチャによってはサポートしていない演算もある。 このような演算に関しては、ターゲットが生成できるノードに変換する…

オリジナルLLVMバックエンド実装をまとめる(18. LLVM IRからInstruction Selectionまでの流れ)

Instruction Selectionでは、LLVM IRを受け取り、それをSelection DAGに変換する。このフェーズは、さらに以下の細かなフェーズに分けることができる。 LLVM IRをSelection DAGへ変換 Selection DAGのCombine Selection DAGのLegalize Selection DAGをMachin…

オリジナルLLVMバックエンド実装をまとめる(17. 関数からも戻るときのCalling Convention)

次に、戻り値に関するCalling Conventionの実装から始める。 以下の記述では、関数の戻り値が渡される場合に、CCAssignToRegで示されるレジスタのどれかに引数が格納されるルールが追加されている。 そしてCalling ConventionであるRetCC_MYRISCVXを定義する…

オリジナルLLVMバックエンド実装をまとめる(16. 関数コールをサポートする)

今までのバックエンドの実装では、関数の取り扱いについていろいろとさぼっている部分があった。今回は、関数の定義と関数コールをきちんとサポートしようと思う。このためには、 スタックフレームの定義 引数の処理 などを実装していく。 現状では、引数の…

オリジナルLLVMバックエンド実装をまとめる(14. 分岐の際に発生する不要なジャンプを削除するPassの追加)

前回の制御構文を追加した際に、不要なジャンプ命令が発生しているのが気になった。例えば、LLVM IRをダンプし時に以下のようなIRが出力されたはずだ。 この時、br label %if.endはすぐ後ろのif.endにジャンプするため、このジャンプ文は不要なはずだ。ここ…

オリジナルLLVMバックエンド実装をまとめる(15. case文で使用されるJumpTableのサポート)

次は、if文を組み合わせたような形で登場するswitch文のサポートを考える。以下のようなコードを用意した。 test_switch.cpp int test_value = 0x30; // 0x30, 0x31, ... ,0x35 int a_val = 0; int b_val = 0; void test_switch () { int result = 0; switch…

オリジナルLLVMバックエンド実装をまとめる(14. 条件分岐命令の生成)

制御フロー生成 いよいよLLVMバックエンドの醍醐味、制御構文の生成に入る。 まずは、以下のような簡単なCプログラムをClangに入力し、LLVM IRを生成してみる。どのような制御IRが必要になるのかを確認する。 if_ctrl.cpp int test_ifctrl() { unsigned int …

オリジナルLLVMバックエンド実装をまとめる(13. 配列・構造体のサポートの確認)

配列のサポートの確認 次に、整数型以外に配列のサポートの確認をする。実は、ここまでの実装で配列はサポートできるようになっている。以下のプログラムをコンパイルしてみる。 int_arary.cpp int int_array() { int array[4] = {100, 200, 300, 400}; int …

オリジナルLLVMバックエンド実装をまとめる(12. int32以外の型のサポートの確認)

これまでの実装で、int型以外の型もサポートできているが、念のために確認しておく。 int32型よりも小さい型を扱うために、これまでに以下のノードを追加していたのだった。 llvm-myriscvx80/lib/Target/MYRISCVX/MYRISCVXInstrInfo.td // Load/Store PatFra…

オリジナルLLVMバックエンド実装をまとめる(11. グローバル変数の生成について)

今回は、グローバル変数を取り扱うための手法について調査する。 現状では、グローバル変数の入っているプログラムをコンパイルすると以下のようにエラーが発生する。 global_access.cpp int global0 = 0; int global1 = 100; void global_access () { int i…

コンピュータアーキテクチャ 定量的アプローチ(ヘネパタ) 第6版日本語版を購入

RISC-V Day Tokyo 2019でも販売したらしいのだが、参加しなかったのでネットで購入。 到着して、開封するととりあえずデカいな! コンピュータアーキテクチャ 第6版 原著と日本語版 中身はまだ熟読していないけど、とりあえず気になるのは2点: 表紙に「第6…

オリジナルLLVMバックエンド実装をまとめる(10. オブジェクトファイルの生成について)

オブジェクトファイルの生成 llcはアセンブリファイルを出力するだけでなく、オブジェクトファイルを出力する機能もある。オブジェクトファイルを出力するためには、llcのオプションで-filetype=asmの代わりに-filetype=objを指定する。 $ ./bin/llc -debug …

オリジナルLLVMバックエンド実装をまとめる(9. emitPrologue, emitEpilogueについて)

関数に関連する命令の生成の続き。関数のプロローグ・エピローグとはどのような処理をするのだろうか。 プロローグ : 関数の先頭で、関数のスタックフレームを生成する。関数が使用する変数のサイズだけスタックを移動し、メモリ領域を確保する。また、Calli…