RISC-VのGDBの動作を検証するために、benchmarkプログラムを動作させてみよう。RISC-Vのベンチマークセットは、riscv-testsに格納されている。
これを動作させてみるために、コンパイルおよび動作の調査を行ったのだが、見たことないシステムレジスタにぶつかった。
HW実装依存になっているシステムレジスタstats,uarch00-15
ベンチマークプログラムの逆アセンブラを調査していると、見たことのないレジスタを発見した。
af4: 0c002573 csrr a0,stats
...
bec: cc002573 csrr a0,uarch0
...
これらのシステムレジスタは、調査してもなかなか情報が出てこなかった。なんだろう?
ツールチェインの情報を見てみると、システムレジスタの領域として、statsは0xc0、uarchは0xcc0-0xccfに配置されている。これは、
- stats : Standard Read/Write
- uarch : Non-standard read-only
として定義されていることを意味する。これらのレジスタを定義して、実装していこう。ただし、機能としてはどのようなものなのか一切説明がないので、とりあえずRWができるだけのシステムレジスタにしておこう。
Benchmarkプログラムを使って動作テスト
riscv-testsに入っている、qsortプログラムを利用した。コンパイルして、実行するだけなので簡単である。
$ ./swimmer_riscv --bit_mode 64 --binfile /home/vagrant/riscv-tools/riscv-tests/benchmarks/qsort.riscv --debug --max 1000000 --trace_hier --trace_out trace.log > debug.log
$ less trace.log
<FunctionCall 98: _init(0x00000f94)>
<FunctionCall 120: memcpy(0x00001098)>
<Return: memcpy>
<FunctionCall 174: thread_entry(0x00000e68)>
<Return: thread_entry>
<FunctionCall 182: main(0x000013a8)>
<FunctionCall 193: sort(0x000004fc)>
<Return: sort>
<FunctionCall 80593: verify.constprop.2(0x000004ac)>
<Return: verify.constprop.2>
<FunctionCall 91865: setStats(0x00000e1c)>
<FunctionCall 91906: handle_trap(0x00000adc)>
<Return: handle_trap>
<Return: setStats>
<FunctionCall 92027: sort(0x000004fc)>
<Return: sort>
<FunctionCall 215655: setStats(0x00000e1c)>
<FunctionCall 215696: handle_trap(0x00000adc)>
<Return: handle_trap>
<Return: setStats>
<FunctionCall 215910: verify.constprop.2(0x000004ac)>
<Return: main>
<FunctionCall 227278: exit(0x00000e08)>
<FunctionCall 227319: handle_trap(0x00000adc)>
<FunctionCall 227334: tohost_exit(0x00000acc)>
$ tail -n debug.log
227328:M:MBar:[00000b00] 00800713 : addi r14,r00,0x008 r00=>0000000000000000 r14<=0000000000000008
227329:M:MBar:[00000b04] 00e50a63 : beq r10,r14,0x00 r10=>0000000000000008 r14=>0000000000000008 pc<=0000000000000b18
227330:M:MBar:[00000b18] 08863703 : ld r14,r12,0x088 r12=>0000000000025660 (00000000000256e8)=>0000005d r14<=000000000000005d
227331:M:MBar:[00000b1c] 05d00693 : addi r13,r00,0x05d r00=>0000000000000000 r13<=000000000000005d
227332:M:MBar:[00000b20] 2cd70c63 : beq r14,r13,0x16 r14=>000000000000005d r13=>000000000000005d pc<=0000000000000df8
227333:M:MBar:[00000df8] 05063503 : ld r10,r12,0x050 r12=>0000000000025660 (00000000000256b0)=>00000000 r10<=0000000000000000
227334:M:MBar:[00000dfc] cd1ff0ef : jal r01,0xcd1ff r01<=0000000000000e00 pc<=0000000000000acc
227335:M:MBar:[00000acc] 00151513 : slli r10,r10,0x01 r10=>0000000000000000 r10<=0000000000000000
227336:M:MBar:[00000ad0] 00156793 : ori r15,r10,0x001 r10=>0000000000000000 r15<=0000000000000001
227337:M:MBar:[00000ad4] 78079073 : csrrw r00,0x780,r15 mtohost=>0000000000000000 r15=>0000000000000001 mtohost<=0000000000000001
最後がmtohost=1で終了しているので、動作は問題なさそうだ。ただし、別のベンチマークプログラムでは動作が誤っているようだ。修正していこう。
dhrystone.riscv : mtohost<=0000000000024b40 median.riscv : mtohost<=0000000000000007 mm.riscv : mtohost<=000000000001c880 mt-matmul.riscv : mtohost<=00000000000293c0 mt-vvadd.riscv : mtohost<=00000000000291c0 multiply.riscv : mtohost<=0000000000000001 qsort.riscv : mtohost<=0000000000000001 rsort.riscv : mtohost<=0000000000000001 spmv.riscv : mtohost<=0000000000000005 towers.riscv : mtohost<=0000000000000001 vvadd.riscv : mtohost<=0000000000000001