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