2019-06-01から1ヶ月間の記事一覧
i32型の変数を引数として渡した関数の場合は、レジスタもスタックもサイズはi32で考えているのでこの場合は問題ないのだが、ではi32よりも小さな型の引数を渡す場合にはどのような処理になっているのだろうか。 この場合は呼び出し規約のルールで型の拡張を…
プロセッサアーキテクチャについて再度復習その2。分岐予測の続き。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してくれて…
最近はプロセッサアーキテクチャについて再度復習しようかと思っている。 読んでいるのはA Survey of Techniques for Dynamic Branch Predictionという論文で、新規技術の解説ではないのだが、現在の有名どころの分岐予測技術についてまんべんなく解説してく…
今までのバックエンドの実装では、関数の取り扱いについていろいろとさぼっている部分があった。今回は、関数の定義と関数コールをきちんとサポートしようと思う。このためには、 スタックフレームの定義 引数の処理 などを実装していく。 現状では、引数の…
関数の呼び出し規約が決まったので、関数呼び出しを含むLLVM IRを処理するフェーズに入る。 まず、LLVM IRをDAGに変換する。 LLVM IRをDAGに変換するのはMYRISCVXTaregtLowerigの仕事だ。 その中で引数の解析とDAG変換を行うための関数はLowerFormalArgument…
前回の制御構文を追加した際に、不要なジャンプ命令が発生しているのが気になる。例えば、LLVM IRをダンプし時に以下のようなIRが出力されたはずだ。この時、br label %if.endはすぐ後ろのif.endにジャンプするため、このジャンプ文は不要なはずだ。ここでは…
RISC-V Workshop Zurichで発表された、RISC-Vのオープンソースのプロセッサコアと環境を提供するためのグループ、OpenHWの概要が発表され、その資料を読んだ。 OpenHW Group Proven Processor IP Corporate & CORE-V Overview https://content.riscv.org/wp-…
SELECTノードは以下の実装を用いてMYRISCVXISD::SELECT_CCに変換する。SELECTノードはカスタム実装に置き換え、(MYRISCVXISDではないデフォルトの)SELECT_CCはCombine時に生成しないようにする。 llvm-myriscvx/lib/Target/MYRISCVX/MYRISCVXISelLowering.cp…
3項演算子をコンパイルしてみると、以下のようなLLVM IRが生成されることが分かる。 int test_movx_1() { volatile int a = 1; int c = 0; c = !a ? 1:3; return c; } ./bin/clang --target=mips-unknown-elf ../lbdex/input/ch8_2_select.cpp -c -emit-llvm…
RISC-V Workshop Zurichで発表されたRISC-V Bit Manipulation Spec 0.90の資料がアップロードされたので、さっそく概要を把握してみる。 ちなみに、詳細な資料はこちらを参照した方がよい。 Better Living Through Bit ManipulationHigher Performance at Lo…
Diplomacyの論文を読むその2.前回の記事は以下。 msyksphinz.hatenablog.com carrv.github.io Diplomatic Design Patterns: A TileLink Case Study https://carrv.github.io/2017/papers/cook-diplomacy-carrv2017.pdf 後半はDiplomacyのデザインパタンにつ…
制御フロー生成 いよいよLLVMバックエンドの醍醐味、制御構文の生成に入る。if文やfor文などの制御構文を生成できるようにしたい。 まずは、以下のような簡単なCプログラムをClangに入力し、LLVM IRを生成してみる。どのような制御IRが必要になるのかを確認…
Rocket Chipのバス設計は非常に読み解くのが難しい。 Rocket Chipのフロントエンドを読み解いていこうと思ったが、フロントエンドのバス接続の部分でさっそく挫折してしまった。 特に、Chiselで記述されたバスプロトコルとLazyModuleを読み解くのが何だか良…
現在は、int型(32ビット整数)のみLLVM IRをサポートしているが、それ以外の型をサポートしたいと思う。32ビット整数、16ビット整数、8ビット整数、そしてBool型をサポートする。 これらの値をメモリアクセスするために、AlignedLoadを拡張して以下のノードを…
RISC-V Workshop Zurichで発表されたRISC-V Vector Extension 0.7.1の資料がアップロードされたので、さっそく概要を把握してみる。 https://content.riscv.org/wp-content/uploads/2019/06/17.40-Vector_RISCV-20190611-Vectors.pdf ちなみに、詳細な資料は…
LLVM IRでポインタのサポートをする。ポインタをサポートするためには、該当するシンボルに対するアドレスを計算するというIRを追加する必要がある。これを、EffectiveAddressというクラスで追加する。 llvm-myriscvx/lib/Target/MYRISCVX/MYRISCVXInstrInfo…
まだすべてチェックしていないが、RISC-V Workshop Zurichのスライドがすべて公開されている。 riscv.org ざっくりとみてみたいのはこのあたりかな。 OpenHW Group Announces CORE-V Family of Open-Source RISC-V Cores https://content.riscv.org/wp-conte…
SiFive Tech Symposiumの時に聞いたのだが、Freedom-E-SDKの時期リリースバージョンではCoremarkが同梱されているらしい。 freedom-e-sdkのブランチをdevelopment-19.05に変更すれば出てくる。 github.com freedom-e-sdkの標準のビルド方法ではビルドできな…
今回は、グローバル変数を取り扱うための手法について調査する。 現状では、グローバル変数の入っているプログラムをコンパイルすると以下のようにエラーが発生する。 int gStart = 3; int gI = 100; int test_global() { int c = 0; c = gI; return c; } ./…
RISC-VのRocket-Chipを勉強していこうと思う。 まずはRocketがどのような階層構成になっているのか、生成されたVerilogを使って把握してみたい。 ずいぶんと古いツールだが、Verilog-Perlの中にvhierというツールが存在する。 metacpan.org 久しぶりにVerilo…
例えば、以下のようなプログラムをコンパイルする。 このプログラムは命令を生成する段階でローテートを示すIRを生成する。 int test_rotate_left() { unsigned int a = 8; int result = ((a << 30) | (a >> 2)); return result; } ./bin/clang -target mips…
定数が生成できるようになったので、次は演算命令を追加する。 こちらも同様にMYRISCVXInstrInfo.tdに命令パタンを追加していく。 llvm-myriscvx/lib/Target/MYRISCVX/MYRISCVXInstrInfo.td def ADDI : ArithLogicI<0b0010011, 0b000, "addi", add, simm12, …
簡単な関数をコンパイルしてアセンブリ命令が出力できるようになったので、様々な命令をサポートしていきましょう。MYRISCVXに命令を追加して、生成できるコードの量を増やしていく。 基本的な算術演算から進めるのが良いと思う。 MYRISCVXに命令を追加する…
2019/06/13(木)~2019/06/14(金)に開催されるET-Westと呼ばれる技術展で、テクニカルセッションとしてRISC-Vに関する講演を行います。 www.jasa.or.jp テクニカルセッション 06/14 13:00 - 14:30 場所 : グランフロント大阪 ナレッジキャピタル コングレコン…
MYRISCVXRegisterInfo::eliminateFrameIndex これも必須の関数だ。関数のスタックフレーム内での参照について、計算できていなかったオフセットを計算するための関数だ。 このeliminateFrameIndexが呼ばれるまでは、スタックポインタをベースに参照されるデ…
最終的に関数をコンパイルして命令を出力するためには、関数のプロローグ・エピローグを生成する必要がある。 関数のプロローグは関数に入った時の最初に行う処理、関数のエピローグは関数から出るときに最後に行う処理である。 基本的には Callee Saved Reg…
UCB(University of California, Berkeley)の論文を教えてもらい、読んでみることにした(実際には大量にGoogle翻訳した)。 この論文は"Generating the Next Wave of Custom Silicon"という論文である。 著者から分かる通り、RISC-VとChiselの思いっきり関係者…
DAG-to-DAGの目的は、ターゲットとは独立したノード情報をターゲット固有のノードに変換する処理を行うことだ。命令を選択するアルゴリズムはSelectionDAGに対して実行される。 DAGToDAGの中で実装しなければならない重要な関数の一つは、アドレスを計算する…
MYRISCVXISelLoweringはLLVM IRからSelectionDAG(データフローグラフ)への変換プロセスになる。 バックエンドのかなり初期の部分で適用される。 ここで必要な実装はMYRISCVXISelLowering.cppを実装する必要がある。 ここではLowerReturnとLowerFormalArgumen…