RISC-V にはRV32とRV64のモードが存在しており、これはアドレッシングモードのみを示しているものと思いがちだが、
と決められている。
For RV32, the x registers are 32 bits wide, and for RV64, they are 64 bits wide.
というわけで、シミュレータを開発する場合は、32ビットのモードと64ビットのモードを両方サポートしなければならないのだが、これを riscv-isa-sim
で実現するためにはどのようになっているのだろうか。
自作シミュレータでは、C++のtemplateを利用して32ビットモードと64ビットモードのコードを両方用意していたのだが、面倒なので統一できるところは統一したい。
riscv-isa-sim における32bitモードと64bitモードのサポートについて
たとえば、riscv-isa-sim
において add
命令の動作については以下のように定義されている。
WRITE_RD(sext_xlen(RS1 + RS2)); #define sext_xlen(x) (((sreg_t)(x) << (64-xlen)) >> (64-xlen)) #define zext_xlen(x) (((reg_t)(x) << (64-xlen)) >> (64-xlen))
つまり、sext_xlen
を使って、32bitモードの場合は64ビットのうち上位はすべて符号ビットで埋めるようにしている。
基本的に32bitモードで整数命令を動かす場合にはこの方式で動作しているようだ。 たとえば、テストパタン内で、sub命令をテストする場合 (以下は自作シミュレータのログ)
50:U:MBar:[80000134][P80000134] 40208f33 : sub r30,r01,r02 ra=>00000003 fp=>00000007 t4<=fffffffc 51:U:MBar:[80000138][P80000138] ffc00e93 : addi r29,r00,ffc zero=>00000000 t3<=fffffffc 52:U:MBar:[8000013c][P8000013c] 00400193 : addi r03,r00,004 zero=>00000000 s1<=00000004 53:U:MBar:[80000140][P80000140] 47df1e63 : bne r30,r29,35 t4=>fffffffc t3=>fffffffc
sub命令の結果はt4<=fffffffc
だが、実際にはt4<=fffffffffffffffc
であり、基本的に比較命令などももISSとしてはすべて64ビットで比較するようになっている。
これに対応させることで、自作シミュレータでもかなりのパタンをパスできるようになった。
400本近くあるパタンのうち、落ちているのは以下のみとなった。
$ grep Fail result.txt rv64si-p-dirty Fail rv64uc-v-rvc Fail rv64mi-p-ma_fetch Fail rv32si-p-sbreak Fail rv64uc-p-rvc Fail rv32ua-v-lrsc Fail rv32si-p-ma_fetch Fail rv64ua-p-lrsc Fail rv32mi-p-breakpoint Fail rv32uc-p-rvc Fail rv32mi-p-ma_fetch Fail rv64si-p-wfi Fail rv32mi-p-mcsr Fail rv32ua-p-lrsc Fail rv32si-p-wfi Fail rv64si-p-ma_fetch Fail rv32si-p-dirty Fail rv64ua-v-lrsc Fail rv64mi-p-ma_addr 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 rv64ud-p-move Fail