福野泰介の一日一創

人気のArmマシン語入門の「つぎのいっぽ」ハンドアセンブルをRISC-Vでやってみました。


参考図書「RISC-V原典 オープンアーキテクチャのススメ | デイビッド・パターソン, アンドリュー・ウォーターマン, 成田 光彰
著者、デイビッド・パターソン氏は、RISC生みの親!

せっかくなのでハンドアセンブルしやすく実行効率の良い、16bitの圧縮命令拡張RV32Cを使いたいので、以前使用したエミュレーターにC拡張を勉強ついでに追加実装。(rv32emuの元、TinyEMUはC対応してます)

R11=0 R11+=R10 R10-=1 IF R10 GOTO -2 R10=R11 RET

RISC-VのC言語呼び出し規約では、R10が第一引数で返り値となり、R11も一時レジスタとして使用可能なので、R10/R11を使用。C拡張の命令のみを使ってasm15r表記で作成。

比較のためにこちらがArm Cortex-M0用、asm15表記ですが、ほぼ同じですね。

R1=0 R0=R0+R1 R0=R0-1 IF !0 GOTO -2 R0=R1 RET

RISC-Vにはフラグがない代わりに分岐命令で比較が可能です(比較した結果を0か1かで代入する命令でキャリーフラグを代用できます)。 足りない命令は、32bit命令を使えばOKなので、割り切ったコンパクトな設計が美しい。

RV32C RISC-Vマシン語表」を見ながらハンドアセンブルします。

0b0010010110000001, // R11=0 0b1001010110101010, // R11+=R10 0b0001010101111101, // R10-=1 0b1111110101110101, // IF R10 GOTO -2 0b1000010100101110, // R10=R11 0b1000000010000010, // RET

こちらを emu-rv32i-test-c.c で、仮想RAMに書き込んで、実行!
繰り返し足し算するプログラムが動きました!(src on GitHub


ArmのThmubと違って、C拡張はハードウェアで実装する別名的扱い。 よく使われる命令に絞って実装されており、32bit命令と併用できるのが特徴。たった400ゲートで実装できると言うだけあって、C言語での実装も約200行とコンパクト。(関数 convert_insn_from_c / src on GitHub

16bit命令を使うことで30%ほど容量が削減できて、ArmのThumbとほぼ近いサイズくらいになります。レジスタを複数PUSHするなどの命令を削減したため、より小さくはなりませんが、ハードウェアコストや実行性能にメリットあり。後発優位でもありますが、この辺りのバランス感覚が気持ちいい。

64bit時代にプログラムの容量削減に意味はあるのか?大有りなのです。メモリとのアクセスは時間がかかるので、何段ものキャッシュを使って実行効率を上げている現代CPU、命令がコンパクトになるとその分キャッシュヒット率が向上し、速く動作するわけです。実行時間=電力消費量=コストなので、省エネ化にもつながります。

RISC-V原典、一番おもしろかったのはV(ベクトル)拡張。CPU+GPUの歴史が変わりそう!V実装のフィックスと実CPUの広まり、大いに楽しみです。
(参考、RISC-Vベクトル拡張について解説する - Fixstars Tech Blog /proc/cpuinfoArm64のSIMD

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / アイコン画像 / プロフィール画像 / RSS