Gem5に命令を追加する試行続き。ベクトル命令を定義するためにどんなことが必要なのかを試行錯誤していた。
まず、ベクトル命令全体を定義するためにRVVLoad
というクラスを定義する。
riscv/isa/formats/rvv_mem.isa
def format RVVLoad(memacc_code, base_reg=[], mem_flags=[], inst_flags=[]) {{ (header_output, decoder_output, decode_block, exec_output) = \ RVVLoadBase(name, Name, memacc_code, base_reg, mem_flags, inst_flags, 'RVVLoad', exec_template_base='RVVLoad') }};
RVVLoadを実際に実行するのが以下の実装だ。
いろいろ訳が分からないだろうが、とりあえず%(...)
で書いてあるものは全部DSLにより置き換わると考えてよろしい。
def template RVVLoadExecute {{ Fault %(class_name)s::execute( ExecContext *xc, Trace::InstRecord *traceData) const { Addr EA; %(op_decl)s; %(op_rd)s; EA = Rs1; MemElemType memdata = 0; { for (int i = 0; i < 16; i++) { Fault fault = readMemAtomicLE(xc, traceData, EA++, memdata, memAccessFlags); if (fault != NoFault) return fault; } } %(memacc_code)s; %(op_wb)s; return NoFault; } }};
実際にReplaceを行うのが以下のコードとなる。これはPythonで記述してあり、かなりいろんな自動生成したファイルをReplaceするためにわけのわからないことをしている。
let {{ def RVVLoadBase(name, Name, memacc_code, base_reg, mem_flags, inst_flags, base_class, postacc_code='', decode_template=BasicDecode, exec_template_base=''): # Make sure flags are in lists (convert to lists if not). mem_flags = makeList(mem_flags) inst_flags = makeList(inst_flags) iop = InstObjParams(name, Name, base_class, {'memacc_code': memacc_code, 'postacc_code': postacc_code, 'base_reg': base_reg}, inst_flags) if mem_flags: mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] s = '\n\tmemAccessFlags = ' + '|'.join(mem_flags) + ';' iop.constructor += s # select templates fullExecTemplate = eval(exec_template_base + 'Execute') initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') completeAccTemplate = eval(exec_template_base + 'CompleteAcc') # (header_output, decoder_output, decode_block, exec_output) return (RVVLoadStoreDeclare.subst(iop), RVVLoadStoreConstructor.subst(iop), decode_template.subst(iop), fullExecTemplate.subst(iop) + initiateAccTemplate.subst(iop) + completeAccTemplate.subst(iop)) }};
いちおういろいろ試行錯誤してビルドは通るようになったが、ベンチマークを実行してみるとやはり失敗してしまった。
Global frequency set at 1000000000000 ticks per second 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/cpu/exec_context.hh:129: panic: ExecContext::readMem() should be overridden Memory Usage: 640752 KBytes Program aborted at tick 11006500
アドレス生成を間違えたかな。もうちょっと試してみたい。