Amazonが発表した自社開発CPU、Graviton2はArmベースでしたが、次世代がRISC-Vになっても不思議はありません。(現時点でAmazonはまだメンバーではないが、オープンに誰でも使えるため、使用するのにメンバーである必要もない)
そんな RISC-V というオープンなコンピューターの気持ちになってみましょう!
IchigoJamで試した、はじめてマシン語Arm編のように、はじめのいっぽはハンドアセンブル!
Specifications - RISC-V Foundation(RISC-V仕様書 P130より)
Instructionsとは、RISC-Vというコンピューターができること一覧、基本は32bit(4byte)、メモリに書かれた命令にしたがって、どんどん計算していきます。 レジスタは基本32コ、そのうち0番レジスタX0は0固定。実行位置を表すプログラムカウンタ(PC)は別となっています。
ひとまず、1+1をさせてみましょう。
レジスタ同士の足し算は ADD (上の図の一番下)
ADD rd,rs1,rs2
rd = rs1 + rs2 という足し算をします。
RISC-Vは、32コあるレジスタ(X0-X31)の内、x10,x11...を引数や、返り値に使うことになっています(x10,x11は別名a0,a1)
ADD x10,x10,x11
こちらをマシン語表を見て、二進法32桁の数値に変換します。(RISC-Vのマシン語の基本は32bit、16bitの圧縮版もあります)
0000000 01011 01010 000 01010 0110011 rs2 rs1 rd
これを16進法に表すと
-> #00b50533
この4byteをメモリに書き込めばOKです!(RISC-Vは、little endian なので、#33,#05,#b5,#00 の順)
ただ、これだけではプログラムの終わりがわからずどんどんよくわからない計算が進んでしまうので、戻す(RETURN)命令を加えます。 RISC-Vでは、戻り先がレジスタ1番に入っているので、そちらへのジャンプ(GOTO)すればOK。 命令表の中から Branch の JALR x1 を上記同様に16進法に変換します。(x1は別名ra)
JALR x1 (JALR rd,rs1) 0b00000000000 000001 000 00000 1100111 rs1 rd -> #00008067
できました!
実機で動かしてみたいところですが、今回は誰でも使えるエミュレーターを使います。
WebAssemblyにも対応し、ブラウザ上でRISC-V版Linux(JSLinux)まで動かしてしまうTinyEMUをベースにしたコンパクトなエミュレーターrv32emuを使います。
いろいろ組み込みに便利なようにコア部分を分離するように改造した rv32emu を作りました。
emu-rv32i.h をインクルードし、下記のように使います。
#include "emu-rv32i.h" #include <stdio.h> int main(int argc, char** argv) { uint32_t start = 0; ram_start = 0; uint32_t end = 0xfffffffe; *(uint*)(ram + start + 0) = 0x00b50533; // ADD x10,x10,x11 *(uint*)(ram + start + 4) = 0x00008067; // JALR x1 pc = start; reg[2] = ram_start + RAM_SIZE; // sp - stack pointer reg[1] = end; // ra - return adderss reg[10] = 1; // a0 reg[11] = 1; // a1 while (machine_running) { next_pc = pc + 4; insn = get_insn32(pc); printf("[%08x]=%08x\n", pc, insn); execute_instruction(); pc = next_pc; if (pc == end) break; } printf("x10 a0: %08x\n", reg[10]); return 0; }
結果はこちら
x10 a0: 00000002
見事、x10に 1+1 の結果、2が入っていますね!
reg[10]やreg[11]の初期値を変えたり、他の命令をハンドアセンブルしてみたりと、いろいろ試してみましょう。
MacでRISC-Vの開発環境を入れるなら、Homebrewを使うと楽ですよ!
$ brew tap riscv/riscv $ brew install riscv-tools