RISC-V向けISSでは、32ビットモードと64bitモードを1つのオプションで混在できるようにしている。
ここ最近、32ビットモードでベンチマークを走らせてどうしても動かない場所があったのだが、突き詰めていくとアドレス計算と符号拡張のところにバグを仕込んでしまっていた。
ISSでは、命令を格納するためにSTLのマップを使い、ベースアドレスから1kB程度のまとめた領域を確保し、まずベースアドレスの計算、当該領域を確保しているならば、オフセット以下の場所に書き込み、という構造をとっている。
ここでバグを仕込んでいたのは、ベースアドレスの計算の際に、32ビットモードでも64bitでアドレスを作っていたのだが、ここで符号拡張をするか否かをキチンと定義しておらず、書き込みの時は上位32ビットを残し、読み込みの時は上位32ビットを切り捨てるような構成にしてしまっているためだった。
これを修正するためには、とりあえず書き込み(hexロード)の時に上位32ビットも符号拡張させるように変更した。
- Addr_t addr = section->vma + i; + + Addr_t addr; + if (FLAGS_bit_mode == 32) { + addr = (int64_t)((int32_t)(section->vma)) + i; + } else { + addr = section->vma + i; + }
ベンチマークの問題は解消するようになった。複数のモードを1つのISSで動的に切り替えるようにしたため、この辺りはいろいろとバグを仕込んでいそうだなあ。。。