SniperにRISC-Vのベンチマークを実行させたくて、マイクロベンチマークをSpike上でシミュレーションしSIFTを生成する試行をしている。 SIFTの生成時にどうもSpikeがハングしてしまうか、予期しない動作をしてしまい様子がおかしい。
どうもみてみると、SIFTを生成する際の挙動に問題があり、ユーザモードでの実行時にはMMUを介するせいでおかしな動作をしてしまうようだ。
いろいろ試行したが、どうやってもMMUを介すると正しくトレースできない。仕方がないので、実行時の命令情報をそのまま記録しておきSIFTを生成する際にはこれを渡すことにした。シーケンシャルに実行しているからこれでいいでしょ。
+uint32_t sift_executed_insn; + + static void commit_log_print_value(FILE *log_file, int width, const void *data) { assert(log_file); @@ -35,9 +38,11 @@ static void commit_log_print_value(FILE *log_file, int width, const void *data) break; case 16: fprintf(log_file, "0x%04" PRIx16, *(const uint16_t *)data); + sift_executed_insn = *(const uint16_t *)data; break; case 32: fprintf(log_file, "0x%08" PRIx32, *(const uint32_t *)data); + sift_executed_insn = *(const uint32_t *)data; break; case 64: fprintf(log_file, "0x%016" PRIx64, *(const uint64_t *)data); @@ -171,6 +176,8 @@ inline void processor_t::update_histogram(reg_t pc) #endif }
+ +extern uint32_t sift_executed_insn; // defined in execute.cc + void getCode(uint8_t *dst, const uint8_t *src, uint32_t size, void* _mmu) { - mmu_t *mmu = reinterpret_cast<mmu_t*>(_mmu); - for (uint32_t i = 0 ; i < size ; ++i) - { - dst[i] = mmu->load_uint8(reinterpret_cast<reg_t>(src)+i); + for (uint32_t i = 0 ; i < size ; ++i) { + dst[i] = sift_executed_insn & 0xff; + sift_executed_insn >>= 8; } + fprintf(stderr, "getCode dst = %02x%02x%02x%02x\n", dst[3], dst[2], dst[1], dst[0]); }
これで、Sniperで一応ベンチマークが動くようになってきた。ただし早速ベクトルの大量のメモリアクセスに引っかかってしまった。 先は長いなあ...