FPGA開発日記

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

サイクルベースシミュレータSniperについて調査する (RISC-Vシミュレーション環境構築の調査)

ビルド中にいろいろ怒られてしまった。

RISCVのデコーダにいくつか古いものがあり、再実装する必要がありそうだ。

diff --git a/decoder_lib/riscv_decoder.cc b/decoder_lib/riscv_decoder.cc
index 08f5bea..16a62c2 100644
--- a/decoder_lib/riscv_decoder.cc
+++ b/decoder_lib/riscv_decoder.cc
@@ -215,6 +215,19 @@ Decoder::decoder_reg RISCVDecoder::mem_base_reg (const DecodedInst * inst, unsig
   return reg;
 }

+bool RISCVDecoder::mem_base_upate(const DecodedInst *inst, unsigned int mem_idx)
+{
+  // riscv::decode *dec = ((RISCVDecodedInst *) ist)->get_rv8_dec();
+  return false;
+}
+
+bool RISCVDecoder::has_index_reg(const DecodedInst *inst, unsigned int mem_idx)
+{
+  // riscv::decode *dec = ((RISCVDecodedInst *) ist)->get_rv8_dec();
+  return false;
+}
+
+
 /// Get the index register of the memory operand pointed by mem_idx
 Decoder::decoder_reg RISCVDecoder::mem_index_reg (const DecodedInst * inst, unsigned int mem_idx)
 {
@@ -545,7 +558,7 @@ std::string format_str(const char* fmt, ...) //rv8 src/util/util.cc
 }

 /// Get a string with the disassembled instruction
-void RISCVDecodedInst::disassembly_to_str(char *str, int len) const
+std::string RISCVDecodedInst::disassembly_to_str() const
 {
   riscv::decode dec = this->rv8_dec;
   std::string args;
@@ -606,8 +619,9 @@ void RISCVDecodedInst::disassembly_to_str(char *str, int len) const
     fmt++;
        }

-  strncpy(str, args.c_str(), len-1);
-  str[len-1] = '\0';
+  return args;
+  // strncpy(str, args.c_str(), len-1);
+  // str[len-1] = '\0';
 }

 /// Check if this instruction is a NOP
@@ -719,4 +733,19 @@ bool RISCVDecodedInst::is_mem_pair() const
   return false;
 }

+bool RISCVDecodedInst::is_indirect_branch() const
+{
+  bool res;
+  riscv::decode dec = this->rv8_dec;
+  switch (dec.op) {
+    case rv_op_jalr:
+    case rv_op_jr:
+      res = true;
+    default :
+      res = false;
+  }
+
+  return res;
+}
+
 } // namespace dl;
diff --git a/decoder_lib/riscv_decoder.h b/decoder_lib/riscv_decoder.h
index 68dbd1c..111df9f 100644
--- a/decoder_lib/riscv_decoder.h
+++ b/decoder_lib/riscv_decoder.h
@@ -122,6 +122,12 @@ class RISCVDecoder : public Decoder

     /// Get the base register of the memory operand pointed by mem_idx
     virtual decoder_reg mem_base_reg (const DecodedInst * inst, unsigned int mem_idx) override;
+
+    /// Check if the base register of the memory operand pointed by mem_idx is also updated
+    virtual bool mem_base_upate(const DecodedInst* inst, unsigned int mem_idx) override;
+    /// Check if the memory operand pointed by mem_idx has an index register
+    virtual bool has_index_reg (const DecodedInst * inst, unsigned int mem_idx) override;
+
     /// Get the index register of the memory operand pointed by mem_idx
     virtual decoder_reg mem_index_reg (const DecodedInst * inst, unsigned int mem_idx) override;

@@ -170,6 +176,18 @@ class RISCVDecoder : public Decoder
     /// Get the value of the last register in the enumeration
     virtual decoder_reg last_reg() override;

+    /// Get the input register mapped. Some registers can be mapped onto the lower bits of others.
+    virtual uint32_t map_register(decoder_reg reg) override { return reg; };
+    ///Get the number of implicit registers that are read by the instruction
+    virtual unsigned int num_read_implicit_registers(const DecodedInst *inst) override { return 0; };
+
+    ///Get the idx implicit source register
+    virtual decoder_reg get_read_implicit_reg(const DecodedInst* inst, unsigned int idx) override { return 0; };
+    ///Get the number of implicit registers that are written by the instruction
+    virtual unsigned int num_write_implicit_registers(const DecodedInst *inst) override { return 0; };
+    ///Get the idx implicit destiny register
+    virtual decoder_reg get_write_implicit_reg(const DecodedInst *inst, unsigned int idx) override { return 0; };
+
     // /// Get the target architecture of the decoder
     // dl_arch get_arch();

@@ -192,7 +210,7 @@ class RISCVDecodedInst : public DecodedInst
     /// Get the instruction numerical Id
     virtual unsigned int inst_num_id() const override;
     /// Get an string with the disassembled instruction
-    virtual void disassembly_to_str(char *, int) const;
+    virtual std::string disassembly_to_str() const;
     /// Check if this instruction is a NOP
     virtual bool is_nop() const override;
     /// Check if this instruction is atomic
@@ -223,6 +241,9 @@ class RISCVDecodedInst : public DecodedInst
     // const uint8_t * & get_code();
     // uint64_t & get_address();

+    virtual bool is_indirect_branch() const override;
+    virtual bool is_writeback() const override { return false; }
+
     private:
      riscv::decode rv8_dec;
      riscv::inst_t rv8_instr;
[CXX   ] sift/recorder/obj-intel64/emulation.o
emulation.cc:12:44: error: ‘PIN_REGISTER’ has not been declared
   12 | static void handleRdtsc(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gdx)
      |                                            ^~~~~~~~~~~~
emulation.cc:12:64: error: ‘PIN_REGISTER’ has not been declared
   12 | static void handleRdtsc(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gdx)
      |                                                                ^~~~~~~~~~~~
emulation.cc: In function ‘void handleRdtsc(LEVEL_VM::THREADID, int*, int*)’:
emulation.cc:24:12: error: request for member ‘dword’ in ‘* gdx’, which is of non-class type ‘int’
   24 |       gdx->dword[0] = res.rdtsc.cycles >> 32;
      |            ^~~~~
emulation.cc:25:12: error: request for member ‘dword’ in ‘* gax’, which is of non-class type ‘int’
   25 |       gax->dword[0] = res.rdtsc.cycles & 0xffffffff;
      |            ^~~~~
emulation.cc: At global scope:
emulation.cc:29:44: error: ‘PIN_REGISTER’ has not been declared
   29 | static void handleCpuid(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gbx, PIN_REGISTER * gcx, PIN_REGISTER * gdx)
      |                                            ^~~~~~~~~~~~
emulation.cc:29:64: error: ‘PIN_REGISTER’ has not been declared
   29 | static void handleCpuid(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gbx, PIN_REGISTER * gcx, PIN_REGISTER * gdx)
      |                                                                ^~~~~~~~~~~~
emulation.cc:29:84: error: ‘PIN_REGISTER’ has not been declared
   29 | static void handleCpuid(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gbx, PIN_REGISTER * gcx, PIN_REGISTER * gdx)
      |                                                                                    ^~~~~~~~~~~~
emulation.cc:29:104: error: ‘PIN_REGISTER’ has not been declared
   29 | ic void handleCpuid(THREADID threadid, PIN_REGISTER * gax, PIN_REGISTER * gbx, PIN_REGISTER * gcx, PIN_REGISTER * gdx)

PIN_REGISTERというデータ型はPin3.20で完全に消滅してしまったらしいので、pin3.20に差し替えて再度ビルドを行わなければならない。

これで再度ビルドするととりあえずSniperのビルドが完了した。

$ ../riscv-tools/RV64G/build-isa-sim/spike --sift dhrystone.sift ../riscv-tools/RV64G/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv
$ ../sniper/run-sniper -v -criscv --traces=dhrystone.sift

うーん、これでももう少し詳細なトレース情報が欲しいな。SIFTファイルのダンプとかできないだろうか?

{'cmdline': ['../../run-sniper', '-v', '-criscv', '--traces=dhrystone.sift'],
 'git_revision': '92b494e5ca1e995efd3951eeb2f35e108f2bb30c',
 'host': 'ms-x1carbon',
 'pin_version': 'unknown',
 'rusage': (0.015923,
            0.016651,
            8132,
            0,
            0,
            0,
            1970,
            2,
            0,
            160,
            0,
            0,
            0,
            0,
            362,
            0),
 'snipercmd': ['bash',
               '-c',
               '/home/msyksphinz/work/sniper/sniper_again/sniper/lib/sniper -c /home/msyksphinz/work/sniper/sniper_again/sniper/config/base.cfg --general/total_cores=1 --general/output_dir=/home/msyksphinz/work/sniper/sniper_again/sniper/riscv/Speckle -g --traceinput/mirror_output=true --config=/home/msyksphinz/work/sniper/sniper_again/sniper/riscv/Speckle/riscv.cfg -g --traceinput/stop_with_first_app=true -g --traceinput/restart_apps=false -g --traceinput/enabled=true -g --traceinput/emulate_syscalls=false -g --traceinput/num_apps=1 -g --traceinput/thread_0=/home/msyksphinz/work/sniper/sniper_again/sniper/riscv/Speckle/dhrystone.sift'],
 't_elapsed': 0.1659700870513916,
 't_start': 1661610907.997592,
 'tracecmds': [],
 'user': 'msyksphinz',
 'vmem': 7409664L}

あとは結果のVisualizationの方法がよくわからない...