RISC-VのISS実装を進めていっている。今回はアトミック演算についてだ。
アトミック演算は、Read Modify Writeを使って実現している。ReadModifyWriteは、メモリからの読み込み、値の変更、メモリへのストアを1つの命令で実現しており、またこれらのメモリアクセスは、同一メモリアドレスに対して別のアクセスが割り込むことがないことが保証されている。これにより、プロセス切り替え場合など、リソース管理が正確に実現できるようになる。
RISC-Vのアトミックアクセス
RISC-Vのアトミックアクセスについては、以下が定義されている。
まず、32ビット版のアトミックアクセスについては以下が定義されている。
次は64ビット版のアトミックアクセスについては以下が定義されている。
これらについては、Privileged Manualに書いてあるとおり、
- rs1のレジスタ値をメモリアドレスとしてデータをロードする。
- ロードしたデータは、そのままレジスタrdに格納される。
- ロードしたデータと、rs2の値を演算し、その結果をrs1のレジスタ値をアドレスとしたメモリ領域にストアする。
これを実装すると、以下のようになった。今回は、最も分かりやすいAMOADD.W命令だ。
UWord_t rs1_val = m_env->GRegRead<Word_t> (rs1_addr);
UWord_t rs2_val = m_env->GRegRead<Word_t> (rs2_addr);
Word_t mem;
m_env->LoadMemory (rs1_val, Size_Word, &mem);
DWord_t ret = mem + rs2_val;
int32_t except = m_env->StoreMemory (rs1_val, ret, Size_Word);
m_env->GRegWrite (rd_addr, mem);
これらを全ての命令分実装した。32ビットも64ビットも全て実装を完了した。
アトミック演算命令を正しく実装したことにより、リグレッションの通過率は85%まで上昇した。
$ ctest ... 433/434 Test #433: rv64ui-v-xor ..................... Passed 0.01 sec Start 434: rv64ui-v-xori 434/434 Test #434: rv64ui-v-xori .................... Passed 0.02 sec 85% tests passed, 65 tests failed out of 434 Total Test time (real) = 6.67 sec The following tests FAILED: 1 - rv32mi-p-csr (Failed) 3 - rv32mi-p-ma_addr (Failed) 4 - rv32mi-p-ma_fetch (Failed) 5 - rv32mi-pm-ipi (Failed) 6 - rv32mi-p-sbreak (Failed)