最近はほとんどテストベンチのメンテナンスを行っていなかったのだが、Privileged Instructions v1.9.1に対応させるために、久し振りにriscv-testsを使ったISSのリグレッションを実行してみた。
しばらくずっと触っていなかったのだけれども、昔メンテナンスして殆どのパタンをISSで通すようにしていたのだけれども、最近やってみると殆ど落ちるようになってしまっていた。
mtohost, mfromhost、各種システムレジスタの廃止
そもそも最初全てのパタンが解析できないようになっていたのだが、どうやらmtohost/mfromhostは廃止されてしまったらしい。 そして、時間計測系のシステムレジスタ(mtime系)のレジスタも廃止されており、csr系命令のアドレスマップも変わっており、相当の変更が必要だ。
テストパタンの終了方式
では、mtohostが廃止されたことにより、riscv-testsはどのようにして計測を終了させるのだろう?
パタンの説明では、どうやら0x8000_1000への書き込みでもってパタンの終了を判定しなければならないらしい。
80000040 <write_tohost>: 80000040: 00001f17 auipc t5,0x1 80000044: fdcf2023 sw t3,-64(t5) # 80001000 <tohost> 80000048: ff9ff06f j 80000040 <write_tohost>
これにより0x8000_1000に書き込まれた値でもってテストパタンの成功失敗を判定しなければならないらしい。
RISC-V ISSの変更 (テストパタンの終了判定)
テストパタンの終了判定条件の追加
そこで、ISSを変更して、RISC-Vのテストパタン終了判定のための機構を取り入れることにした。
具体的には、0x8000_1000にアクセスした場合にそこで終了し、テストパタンの結果を返すことにする。このままだと他のベンチマークプログラムに影響してしまうが、それは後で修正する。
新規命令の追加 (mret/sret/hret/uret)命令の追加
これまでは一つのsret命令だけだったのだが、Privileged Instruction v.1.9.1ではそれぞれ別々の命令として定義されている。
それぞれの命令を追加した。
リグレッション結果
いつの間にかめっちゃ落ちるようになってるなあ。。。
12% tests passed, 350 tests failed out of 398 Total Test time (real) = 315.32 sec The following tests FAILED: 1 - rv32mi-p-breakpoint (Failed) 2 - rv32mi-p-csr (Failed) 3 - rv32mi-p-illegal (Failed) 4 - rv32mi-p-ma_addr (Failed) ...
12%しかPASSしてない!
2018/06/09追記。テストパタンの終了条件は、テストバイナリ中のtohost
にアクセスすればシミュレーション終了とできる。
現在テストパタンによってはこの場所が異なっているので注意。
バイナリをロードして、tohostの位置をチェックしてテストの終了条件を変える。
$riscv64-unknown-elf-objdump -D /home/msyksphinz/riscv64/riscv64-unknown-elf/share/riscv-tests/isa/rv64ud-p-move セクション .tohost の逆アセンブル: 0000000080002000 <tohost>: ... 0000000080002040 <fromhost>:
- riscv_pe_thread.cpp
MemResult RiscvPeThread::StoreToBus (Addr_t addr, Size_t size, Byte_t *data) { Addr_t paddr, internal_paddr; MemResult mem_result = ConvertVirtualAddress (&paddr, addr, MemAccType::WriteMemType); if (mem_result != MemResult::MemNoExcept) { return mem_result; } Addr_t mtohost_addr; if (FindGVarAddr (&mtohost_addr, "tohost") == true) { // ここでチェック。速度的に問題ありだな。毎回チェックする必要はないが... if (paddr == mtohost_addr) { SetStopSim (true); // if MTOHOST is hit, ready to stop simulation Word_t result; memcpy (&result, data, 4); SetResult (result); } }
これでテストがかなりパスするようになった。401本中Passは379本となった。
$ grep Fail result.txt rv64si-p-dirty Fail rv32si-p-sbreak Fail rv64uc-v-rvc Fail rv32ua-v-lrsc Fail rv64um-p-divu Fail rv64ua-p-lrsc Fail rv32mi-p-breakpoint Fail rv64si-p-wfi Fail rv32mi-p-mcsr Fail rv32ua-p-lrsc Fail rv32si-p-wfi Fail rv32si-p-dirty Fail rv64ua-v-lrsc Fail rv64mi-p-ma_addr Fail rv64um-v-divu Fail rv32mi-p-sbreak Fail rv32mi-p-ma_addr Fail rv32uc-v-rvc Fail rv32mi-p-shamt Fail rv64mi-p-breakpoint Fail rv64mi-p-illegal Fail rv32mi-p-illegal Fail