前回まででRocketChipのカスタマイズと、binutilsのカスタマイズが完了した。 今回はRocketChipのシミュレーションをして動作確認してみよう。
bitrev命令のテストプログラムを作成する
新規命令のテストプログラムを作成するには、riscv-toolsの環境を使うのが便利だ。riscv-toolsは大きく分けでISAのテストをするためのisa/
ディレクトリと、ベンチマークプログラムを動作させるためのbenchmarks/
ディレクトリに分かれている。
ISAのテストディレクトリは様々なモード向けにちょっと複雑な構成になっているため、直感的に追加できるbenchmarksディレクトリに対してプログラムを追加した。
riscv-tools/riscv-tests/benchmarks$ tree bitrev bitrev └── bitrev.c 0 directories, 1 file
bitrev.cの中身は以下のように記述した。
int main (int argc, char *argv []) { int x = 0x01234567; volatile int y; __asm__ ("bitrev %0, %1" :"=r"(y) :"r"(x) : ); return 0; }
これでbenchmarks/
ディレクトリの上でmakeを実行すると、それ以外のベンチマークプログラムに加えて、bitrevのプログラムもコンパイルされる。
生成されたbitrev.riscv
がバイナリファイル、bitrev.riscv.dump
がダンプファイルだ。
セクション .text.startup の逆アセンブル: 0000000080001778 <main>: 80001778: 1141 addi sp,sp,-16 8000177a: 012347b7 lui a5,0x1234 8000177e: 5677879b addiw a5,a5,1383 80001782: 0007878b bitrev a5,a5 80001786: c63e sw a5,12(sp) 80001788: 4501 li a0,0 8000178a: 0141 addi sp,sp,16 8000178c: 8082 ret 8000178e: 1141 addi sp,sp,-16 80001790: 00000517 auipc a0,0x0 80001794: 19050513 addi a0,a0,400 # 80001920 <main+0x1a8> 80001798: e406 sd ra,8(sp) 8000179a: cc9ff0ef jal ra,80001462 <printstr> 8000179e: 60a2 ld ra,8(sp) 800017a0: 557d li a0,-1 800017a2: 0141 addi sp,sp,16 800017a4: 8082 ret
mainの中に、bitrev命令が入った。このバイナリファイルを指定して、RocketChipを動かしてみよう。
RocketChipの評価リポジトリのemulator/
に移動し、評価用のバイナリファイルをシンボリックリンクで指定する。
以下で実行可能だ。
cd emulator mkdir output cd output ln -s /PATH/TO/bitrev.riscv bitrev cd ../ make output/bitrev.out
実行が完了すると、output/bitrev.out
にトレースログが出力される。確認してみよう。
C0: 61842 [1] pc=[008000164a] W[r10=0000000000000000][1] R[r 0=0000000000000000] R[r 0=0000000000000003] inst=[00000513] li a0, 0 C0: 61843 [1] pc=[008000164c] W[r 1=0000000080001650][1] R[r 0=0000000000000000] R[r12=0000000000000003] inst=[12c000ef] jal pc + 0x12c C0: 61871 [1] pc=[0080001778] W[r 2=00000000800218b0][1] R[r 2=00000000800218c0] R[r16=0000000000000003] inst=[ff010113] addi sp, sp, -16 C0: 61872 [1] pc=[008000177a] W[r15=0000000001234000][1] R[r 6=00000000800218c3] R[r18=0000000000000003] inst=[012347b7] lui a5, 0x1234 C0: 61897 [1] pc=[008000177e] W[r15=0000000001234567][1] R[r15=0000000001234000] R[r 7=0000000000000003] inst=[5677879b] addiw a5, a5, 1383 C0: 61898 [1] pc=[0080001782] W[r 0=00000000e6a2c480][0] R[r15=0000000001234567] R[r 0=0000000000000000] inst=[0007878b] custom0 (args unknown) C0: 61919 [1] pc=[0080001786] W[r 0=00000000800218bc][0] R[r 2=00000000800218b0] R[r15=0000000001234567] inst=[00f12623] sw a5, 12(sp) C0: 61920 [1] pc=[0080001788] W[r10=0000000000000000][1] R[r 0=0000000000000000] R[r 0=0000000001234567] inst=[00000513] li a0, 0 C0: 61921 [1] pc=[008000178a] W[r 2=00000000800218c0][1] R[r 2=00000000800218b0] R[r16=0000000001234567] inst=[01010113] addi sp, sp, 16
0x0080001778
がmainの開始位置。custom0はトレースファイルが対応していないためこのような表記になっているが、bitrev命令が実行されており、
0x01234567
→ e6a2c480
にビット位置を反転させる命令が実行できていることが分かる。成功だ!