FPGA開発日記

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

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

LLVMのバックエンドを作るための第一歩 (45. Atomic命令を生成する)

C++ではスレッド機能がサポートされており、ClangでもLLVM IRがサポートされている。例えば、以下のようなコードでIRを出力してみる。 cpp_atomic.cpp #include <stdint.h> #include <atomic> int test_32() { std::atomic<int> x(3); int before = x.fetch_add(2); return x.load()</int></atomic></stdint.h>…

RISC-V Privileged ISAマニュアル20190608-Priv-MSU-Ratified版の変更点を読み解く

"The RISC-V Instruction Set Manual. Volume II: Privileged ISA Document Version 20190608-Priv-MSU-Ratified" が公開されてしばらくたったのだが、少し時間ができたので変更点の部分を簡単に調べてみることにした。 riscv.org 各モードの状態について。 …

RISC-V Unprivileged ISAマニュアル20190608-Base-Ratified版の変更点を読み解く

"The RISC-V Instruction Set Manual. Volume I: Unprivileged ISA Document Version 20190608-Base-Ratified" が公開されてしばらくたったのだが、少し時間ができたので変更点の部分を簡単に調べてみることにした。 riscv.org 命令セットの分類は以下のよう…

高性能プロセッサの分岐予測のサーベイ論文を読んで分岐予測について学ぶ (7. 予測精度を上げるためのテクニック1)

プロセッサアーキテクチャについて再度復習その7。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…

高性能プロセッサの分岐予測のサーベイ論文を読んで分岐予測について学ぶ (5. ハイブリッド分岐予測器)

プロセッサアーキテクチャについて再度復習その6。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…

LLVMのバックエンドを作るための第一歩 (44. 拡張Inline Assemblyのサポート)

次にコンパイルしたいのは、以下のようなCコードだ。 inline_assembly2.cpp int global_data = 200; void test () { int add_res; int b = 200, c = 300; __asm__ __volatile__("add %0,%1,%2" :"=r"(add_res) :"r"(b), "r"(c) ); int lw_res; int *lw_p = (…

オープンソースのMarkdownエディタならばMarkTextが良い感じ

最近はMarkdownを書くのにエディタとしてTyporaを使っている。Typora自体には何も不安がないが、オープンソースでないというところだけが少し引っかかる(別にオープンソースでなくても便利なので使うのだが)。 ※ 大体オープンソースであろうがなかろうが普通…

LLVMのバックエンドを作るための第一歩 (43. インラインアセンブリをサポートする)

llcにアセンブラをサポートする。具体的には、インラインアセンブリなどのC言語の内部にアセンブラを埋め込む処理をサポートする。これまで、さんざんアセンブリ言語のサポートを追加してきたじゃないか、と思うかもしれないが、インラインアセンブリでのア…

LLVMのバックエンドを作るための第一歩 (42. LLVM IRをサポートするためのIntrinsicsを実装する)

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

RISC-Vのベクトル拡張命令RVVの環境を試す (2. ベクトル命令を使ったサンプルプログラムの作成)

RISC-Vのベクトル拡張命令であるRISC-V Vector Extensionは仕様の策定されており、徐々に実装が進んでいる。 riscv-toolsのSpike命令セットシミュレータ riscv-gnu-toolchainの対応 前回ツールセットのインストールが完了したので、今回はサンプルプログラム…

LLVM Armバックエンド脆弱性 stack protectorとは何なのか

LLVMの脆弱性の話が出てきたので、掘り下げてみることにした。まだ理解できていないことが多いが、このような機能があるのだと思って勉強になった。 事の発端は、LLVMのArmバックエンドにおいて、スタックスロットの割り当てについてバグがあったという話。 …

LLVMのバックエンドを作るための第一歩 (41. objdumpのコードを読み解く)

現状、llvm-objdumpを実行すると以下のようになってしまう。これをサポートする。 % ./bin/llvm-objdump -d if_ctrl.o if_ctrl.o: file format ELF32-myriscvx if_ctrl.o': can't find target: : error: unable to get target for 'unknown--', see --versio…

Chiselでfor文を用いた同一モジュールの複数インスタンス化の方法

Verilogでは、同一モジュールを複数インスタンスするときは以下のようにgenerate forが使える。 for (genvar i=1; i<=10; i=i+1) begin subblock u_subblock( .clk(clk), .reset_n(reset_n), .a(a[i]), .b(b[i]), .out(out[i]) ); end これと同様に、Chisel…

LLVMのバックエンドを作るための第一歩 (40. objdumpのサポート)

現状、llvm-objdumpを実行すると以下のようになってしまう。これをサポートする。 % ./bin/llvm-objdump -d results/if_ctrl-O0_-march=mips_-relocation-model=static/if_ctrl.bc ./bin/llvm-objdump: error: 'results/if_ctrl-O0_-march=mips_-relocation-…

「ハロー "Hello, World"」を読み始めた

だいぶスタートダッシュが遅れたが、「ハロー"Hello, World"」を読み始めた。 最初からかなりしっかり説明があるが、いきなりprintf()の中に飛び込んだので若干の低レイヤの知識があった方が読みやすいように思う。 ハロー“Hello, World” OSと標準ライブラリ…

RISC-Vのベクトル拡張命令RVVの環境を試す (1. gccのビルドとシミュレータのビルド)

RISC-Vのベクトル拡張命令であるRISC-V Vector Extensionは仕様の策定されており、徐々に実装が進んでいる。 riscv-toolsのSpike命令セットシミュレータ riscv-gnu-toolchainの対応 現在の実装の状況を見てみることにした。 riscv-toolsのインストール riscv…

高性能プロセッサの分岐予測のサーベイ論文を読んで分岐予測について学ぶ (7. RISC-VのアウトオブオーダコアBOOMのGshare実装を見てみる)

プロセッサアーキテクチャについて再度復習その7。分岐予測の基本について学んだので、実際の実装を見てみたいと思う。 RISC-VのアウトオブオーダBOOMの実装を眺めてみることにした。こちらはChiselをベースにしているので読み解くのは少し厄介だが、できな…

高性能プロセッサの分岐予測のサーベイ論文を読んで分岐予測について学ぶ (6. RISC-VのアウトオブオーダコアBOOMのTAGE実装を見てみる)

プロセッサアーキテクチャについて再度復習その6。分岐予測の基本について学んだので、実際の実装を見てみたいと思う。 RISC-VのアウトオブオーダBOOMの実装を眺めてみることにした。こちらはChiselをベースにしているので読み解くのは少し厄介だが、できな…

LLVMのバックエンドを作るための第一歩 (39. 可変長引数で生成されたアセンブリを見てみる)

前回の続き。サンプルプログラムをコンパイルして、どのようなアセンブリ言語が出力されるのか観察する。 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 < amo</stdarg.h>…

LLVMのバックエンドを作るための第一歩 (38. 可変長引数のサポート)

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のバックエンドを作るための第一歩 (38. 可変長引数のサポート)

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のバックエンドを作るための第一歩 (37. 構造体を値渡しするためのByval属性の引数 2)

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

高性能プロセッサの分岐予測のサーベイ論文を読んで分岐予測について学ぶ (4. 予測が難しい分岐のための分岐予測器 2)

プロセッサアーキテクチャについて再度復習その5。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…

高性能プロセッサの分岐予測のサーベイ論文を読んで分岐予測について学ぶ (4. 予測が難しい分岐のための分岐予測器)

プロセッサアーキテクチャについて再度復習その4。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…

LLVMのバックエンドを作るための第一歩 (37. 構造体を値渡しするためのByval属性の引数 1)

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

LLVMのバックエンドを作るための第一歩 (36. 末尾関数呼び出し最適化を実装する2)

最後に、アセンブリの生成です。TAILCALLとTAILCALL_Rは疑似命令なのでそのままではアセンブリ命令を出力することができない。これを置き換える処理は、tdファイルからすでに生成されている。MYRISCVXGenMCPseudoLowering.incを見てみみる。 build-myriscvx/…

LLVMのバックエンドを作るための第一歩 (35. 末尾関数呼び出し最適化を実装する1)

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

LLVMのバックエンドを作るための第一歩 (34. 関数コールと戻り値に関するDAGを生成する)

3. 関数呼び出しのDAG生成 次に、ジャンプ先となる関数のアドレスを計算する。PICモードでコンパイルしている場合はGOT経由でのアドレスを計算、そうでない場合はっ直接アドレスの計算を行う。これをGlobalAddressSDNode, ExternalSymbolSDNodeのタイプに対…

LLVMのバックエンドを作るための第一歩 (33. 関数コールに関するLLVM IRをDAGに変換する)

関数コールに関するLLVM IRをDAGに変換するためには、MYRISCVXTaregtLowering::LowerCallを実装する。LowerCallの役割を理解するために、LowerCallのコメントを読んでみる。 llvm-myriscvx/include/llvm/CodeGen/TargetLowering.h /// This hook must be imp…

高性能プロセッサの分岐予測のサーベイ論文を読んで分岐予測について学ぶ (3. Biased分岐予測、TAGE分岐予測)

プロセッサアーキテクチャについて再度復習その2。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…