FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-Vの32bitモードと64bitモードの動作の違いについて

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

f:id:msyksphinz:20180421185728p:plain