2019-07-01から1ヶ月間の記事一覧
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>…
"The RISC-V Instruction Set Manual. Volume II: Privileged ISA Document Version 20190608-Priv-MSU-Ratified" が公開されてしばらくたったのだが、少し時間ができたので変更点の部分を簡単に調べてみることにした。 riscv.org 各モードの状態について。 …
"The RISC-V Instruction Set Manual. Volume I: Unprivileged ISA Document Version 20190608-Base-Ratified" が公開されてしばらくたったのだが、少し時間ができたので変更点の部分を簡単に調べてみることにした。 riscv.org 命令セットの分類は以下のよう…
プロセッサアーキテクチャについて再度復習その7。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…
プロセッサアーキテクチャについて再度復習その6。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…
次にコンパイルしたいのは、以下のような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を書くのにエディタとしてTyporaを使っている。Typora自体には何も不安がないが、オープンソースでないというところだけが少し引っかかる(別にオープンソースでなくても便利なので使うのだが)。 ※ 大体オープンソースであろうがなかろうが普通…
llcにアセンブラをサポートする。具体的には、インラインアセンブリなどのC言語の内部にアセンブラを埋め込む処理をサポートする。これまで、さんざんアセンブリ言語のサポートを追加してきたじゃないか、と思うかもしれないが、インラインアセンブリでのア…
LLVM IRをサポートするためのIntrinsicsのサポート LLVM IRには、いくつかの特殊な構文が存在し、これらをサポートすることでより多くのコードを生成できるようになる。 これらについては、clang側からIntrinsic関数を呼び出すことでLLVM IRを生成し、llcに…
RISC-Vのベクトル拡張命令であるRISC-V Vector Extensionは仕様の策定されており、徐々に実装が進んでいる。 riscv-toolsのSpike命令セットシミュレータ riscv-gnu-toolchainの対応 前回ツールセットのインストールが完了したので、今回はサンプルプログラム…
LLVMの脆弱性の話が出てきたので、掘り下げてみることにした。まだ理解できていないことが多いが、このような機能があるのだと思って勉強になった。 事の発端は、LLVMのArmバックエンドにおいて、スタックスロットの割り当てについてバグがあったという話。 …
現状、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…
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-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"」を読み始めた。 最初からかなりしっかり説明があるが、いきなりprintf()の中に飛び込んだので若干の低レイヤの知識があった方が読みやすいように思う。 ハロー“Hello, World” OSと標準ライブラリ…
RISC-Vのベクトル拡張命令であるRISC-V Vector Extensionは仕様の策定されており、徐々に実装が進んでいる。 riscv-toolsのSpike命令セットシミュレータ riscv-gnu-toolchainの対応 現在の実装の状況を見てみることにした。 riscv-toolsのインストール riscv…
プロセッサアーキテクチャについて再度復習その7。分岐予測の基本について学んだので、実際の実装を見てみたいと思う。 RISC-VのアウトオブオーダBOOMの実装を眺めてみることにした。こちらはChiselをベースにしているので読み解くのは少し厄介だが、できな…
プロセッサアーキテクチャについて再度復習その6。分岐予測の基本について学んだので、実際の実装を見てみたいと思う。 RISC-VのアウトオブオーダBOOMの実装を眺めてみることにした。こちらはChiselをベースにしているので読み解くのは少し厄介だが、できな…
前回の続き。サンプルプログラムをコンパイルして、どのようなアセンブリ言語が出力されるのか観察する。 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>…
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>…
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>…
ByVal属性の値を関数の引数として受け渡す処理の続き。 それでは、次に呼び出し側はどのようになっているのだろうか。呼び出し側でも、ByVal属性のついた引数を一つ一つコピーして関数呼び出され側に渡す必要がある。関数呼び出し側は、MYRISCVXTargetLoweri…
プロセッサアーキテクチャについて再度復習その5。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…
プロセッサアーキテクチャについて再度復習その4。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…
今までの関数処理の中で、引数は基本的にポインタか値渡し、そして値も何らかの型の値を1つずつ渡していくという形式だった。しかし、C言語では構造体などの複数の要素をまとめた型を渡すことができる。また、C言語では構造体の値をそのまま値渡しで引数とし…
最後に、アセンブリの生成です。TAILCALLとTAILCALL_Rは疑似命令なのでそのままではアセンブリ命令を出力することができない。これを置き換える処理は、tdファイルからすでに生成されている。MYRISCVXGenMCPseudoLowering.incを見てみみる。 build-myriscvx/…
関数呼び出しには様々な最適化の形があるが、その中の一つである末尾関数呼び出しでの最適化を実行してみる。末尾関数呼び出しとは、ある関数f1()が関数f2()の最後の処理として呼び出されるケースを言う。 int f1(a, b) { a + b; } int f2(c, d, e, f) { /* …
3. 関数呼び出しのDAG生成 次に、ジャンプ先となる関数のアドレスを計算する。PICモードでコンパイルしている場合はGOT経由でのアドレスを計算、そうでない場合はっ直接アドレスの計算を行う。これをGlobalAddressSDNode, ExternalSymbolSDNodeのタイプに対…
関数コールに関するLLVM IRをDAGに変換するためには、MYRISCVXTaregtLowering::LowerCallを実装する。LowerCallの役割を理解するために、LowerCallのコメントを読んでみる。 llvm-myriscvx/include/llvm/CodeGen/TargetLowering.h /// This hook must be imp…
プロセッサアーキテクチャについて再度復習その2。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…