FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages

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という論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…

LLVMのバックエンドを作るための第一歩 (32. 関数を呼び出す側のDAGの作成:ノードの定義)

引数のある関数を変換するにあたり、関数本体側の引数を取り込む処理は完成したのだが、次は関数を呼び出す側だ。関数コールにあたり、引数をABIのルールに則ってレジスタもしくはスタックに配置する必要がある。 関数呼び出し側の処理を行うためには、MYRIS…

LLVMのバックエンドを作るための第一歩 (31. i32よりも小さな値を引数に渡すとどのようなDAGになるのか)

i32型の変数を引数として渡した関数の場合は、レジスタもスタックもサイズはi32で考えているのでこの場合は問題ないのだが、ではi32よりも小さな型の引数を渡す場合にはどのような処理になっているのだろうか。 この場合は呼び出し規約のルールで型の拡張を…

高性能プロセッサの分岐予測のサーベイ論文を読んで分岐予測について学ぶ (2. 2レベル分岐予測器の構成について)

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

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

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

LLVMのバックエンドを作るための第一歩 (29. 関数コールのサポート: Calling Conventionの定義)

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

LLVMのバックエンドを作るための第一歩 (30. 関数コールのサポート: LowerFormalArgumentsの実装)

関数の呼び出し規約が決まったので、関数呼び出しを含むLLVM IRを処理するフェーズに入る。 まず、LLVM IRをDAGに変換する。 LLVM IRをDAGに変換するのはMYRISCVXTaregtLowerigの仕事だ。 その中で引数の解析とDAG変換を行うための関数はLowerFormalArgument…

LLVMのバックエンドを作るための第一歩 (28. 分岐の際に発生する不要なジャンプを削除するPassの追加)

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

RISC-V Workshop Zurichで発表されたOpenHWグループの概要

RISC-V Workshop Zurichで発表された、RISC-Vのオープンソースのプロセッサコアと環境を提供するためのグループ、OpenHWの概要が発表され、その資料を読んだ。 OpenHW Group Proven Processor IP Corporate & CORE-V Overview https://content.riscv.org/wp-…