Gem5の命令定義表を理解したいので、まずは簡単にRISC-Vのベクトル命令を追加していく。 一番簡単なmemcpyを動かすためには、以下の3つの命令が定義できていれば十分だ。
copy_data_vec: mv a3, a0 # Copy destination .loop: vsetvli t0, a3, e8,m1 # Vectors of 8b vle8.v v0, (a1) # Load bytes add a1, a1, t0 # Bump pointer sub a2, a2, t0 # Decrement count vse8.v v0, (a3) # Store bytes add a3, a3, t0 # Bump pointer bnez a2, .loop # Any more? ret # Return
Gem5の命令テーブルを見ながら、地味に追加していく。
diff --git a/src/arch/riscv/insts/SConscript b/src/arch/riscv/insts/SConscript index 80592a34e..c20e8810b 100644 --- a/src/arch/riscv/insts/SConscript +++ b/src/arch/riscv/insts/SConscript @@ -32,3 +32,4 @@ Source('compressed.cc', tags='riscv isa') Source('mem.cc', tags='riscv isa') Source('standard.cc', tags='riscv isa') Source('static_inst.cc', tags='riscv isa') +Source('rvv_mem.cc', tags='riscv isa') diff --git a/src/arch/riscv/insts/static_inst.cc b/src/arch/riscv/insts/static_inst.cc index 6f6b3fe7b..86efcaf7e 100644 --- a/src/arch/riscv/insts/static_inst.cc +++ b/src/arch/riscv/insts/static_inst.cc @@ -62,5 +62,6 @@ RiscvMicroInst::advancePC(ThreadContext *tc) const tc->pcState(pc); } + } // namespace RiscvISA } // namespace gem5 diff --git a/src/arch/riscv/insts/static_inst.hh b/src/arch/riscv/insts/static_inst.hh index eec9c8828..728ef442d 100644 --- a/src/arch/riscv/insts/static_inst.hh +++ b/src/arch/riscv/insts/static_inst.hh @@ -88,6 +88,10 @@ class RiscvStaticInst : public StaticInst { return simpleAsBytes(buf, size, machInst); } + + void printMnemonic(std::ostream &os, + const std::string &suffix = "") const; + }; /** diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index 6cd7d952e..d5340a062 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -427,6 +427,15 @@ decode QUADRANT default Unknown::unknown() { fd = freg(f64(Mem)); Fd_bits = fd.v; }}, inst_flags=FloatMemReadOp); + 0x0: vle8({{ + // STATUS status = xc->readMiscReg(MISCREG_STATUS); + // if (status.fs == FPUStatus::OFF) + // return std::make_shared<IllegalInstFault>( + // "FPU is off", machInst); + freg_t fd; + fd = freg(f16(Mem_uh)); + Fd_bits = fd.v; + }}, inst_flags=FloatMemReadOp); } } @@ -621,6 +630,9 @@ decode QUADRANT default Unknown::unknown() { Mem_ud = Fs2_bits; }}, inst_flags=FloatMemWriteOp); + 0x0: vse8({{ + Mem_uh = (uint16_t)Fs2_bits; + }}, inst_flags=FloatMemWriteOp); } } @@ -1887,5 +1899,15 @@ decode QUADRANT default Unknown::unknown() { } 0x1e: M5Op::M5Op(); - } + + 0x15: decode FUNCT3 { + 0x7: decode IMMSIGN { + format CSROp { + 0x0 : vsetvli({{Rd = data; + data = Rs1; + }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); + } + } + } + } }
再度Gem5をビルドして、memcpyのベンチマークを実行していく。
warn: No dot file generated. Please install pydot to generate the dot file and pdf. build/RISCV/mem/dram_interface.cc:690: warn: DRAM device capacity (8192 Mbytes) does not match the address range assigned (512 Mbytes) 0: system.remote_gdb: listening for remote gdb on port 7000 **** REAL SIMULATION **** build/RISCV/sim/simulate.cc:194: info: Entering event queue @ 0. Starting simulation... build/RISCV/sim/mem_state.cc:443: info: Increasing stack size by one page. build/RISCV/sim/syscall_emul.cc:74: warn: ignoring syscall mprotect(...) build/RISCV/sim/faults.cc:102: panic: panic condition !handled && !tc->getSystemPtr()->trapToGdb(SIGSEGV, tc->contextId()) occurred: Page table fault when accessing virtual address 0xc1050 Memory Usage: 633320 KBytes Program aborted at tick 5393500
うーん、ページテーブルエラー?普通の命令が動いているはずだからおかしいなあ... VLE8とVSE8をベンチマークから取り除くと動くので、間違いなくこの2つの命令の挙動がおかしい。 もうちょっと解析してみよう。