RISC-Vの拡張を増やしたい場合、以下のようにしてターゲットとなるファイルの指定を増やす。
cat riscv/riscv-tools/riscv-opcodes/opcodes \\
riscv/riscv-tools/riscv-opcodes/opcodes-rvc \\
riscv/riscv-tools/riscv-opcodes/rv_zba \\
riscv/riscv-tools/riscv-opcodes/rv_zbb | \\
python3 riscv/scripts/generate_decoder.py /dev/stdin \\
> decoder_lib/riscv_decoder_generated.h
分類の関数は、さすがに自分で組まないといけないが…
def classify_instruction(name): # ...既存の分類... elif name.startswith(('andn', 'orn', 'clz', 'ctz')): return 'bitmanip' # ...
より多くの命令に対応させるために、以下のようにしてデコーダを生成した。
cat riscv/riscv-opcodes-latest/extensions/rv_i \ riscv/riscv-opcodes-latest/extensions/rv64_i \ riscv/riscv-opcodes-latest/extensions/rv_m \ riscv/riscv-opcodes-latest/extensions/rv64_m \ riscv/riscv-opcodes-latest/extensions/rv_a \ riscv/riscv-opcodes-latest/extensions/rv64_a \ riscv/riscv-opcodes-latest/extensions/rv_f \ riscv/riscv-opcodes-latest/extensions/rv64_f \ riscv/riscv-opcodes-latest/extensions/rv_d \ riscv/riscv-opcodes-latest/extensions/rv64_d \ riscv/riscv-opcodes-latest/extensions/rv_c \ riscv/riscv-opcodes-latest/extensions/rv64_c \ riscv/riscv-opcodes-latest/extensions/rv64_zba \ riscv/riscv-opcodes-latest/extensions/rv64_zbb \ riscv/riscv-opcodes-latest/extensions/rv64_zbs \ riscv/riscv-opcodes-latest/extensions/rv_v | \ python3 riscv/scripts/generate_decoder.py /dev/stdin > \ decoder_lib/riscv_decoder_generated.
ちゃんとデコーダは生成できるが、より詳細なデータは正しく生成できない。これは riscv-opcodes にも存在していない情報だということか…
これらは、 generate_decoder.py を無理やり改造することで対応するが、あまりきれいじゃないな。
def classify_instruction(name): """Classify instruction by type""" if name.startswith(('beq', 'bne', 'blt', 'bge', 'bltu', 'bgeu', 'c.beqz', 'c.bnez')): return 'branch' elif name.startswith(('jal', 'jalr', 'c.j', 'c.jal')): return 'jump' # Load instructions (scalar + vector) elif name.startswith(('lb', 'lh', 'lw', 'ld', 'lbu', 'lhu', 'lwu', 'flw', 'fld', 'c.lw', 'c.ld', 'c.lwsp', 'c.ldsp', 'c.flw', 'c.fld', 'c.flwsp', 'c.fldsp', 'vle', 'vlse', 'vluxei', 'vloxei', 'vl1re', 'vl2re', 'vl4re', 'vl8re', 'vlm.v', 'vle8.v', 'vle16.v', 'vle32.v', 'vle64.v')): return 'load' # Store instructions (scalar + vector) elif name.startswith(('sb', 'sh', 'sw', 'sd', 'fsw', 'fsd', 'c.sw', 'c.sd', 'c.swsp', 'c.sdsp', 'c.fsw', 'c.fsd', 'c.fswsp', 'c.fsdsp', 'vsuxei', 'vsoxei', 'vsse', 'vsm.v', 'vse8.v', 'vse16.v', 'vse32.v', 'vse64.v')) and not name.startswith('vset'): return 'store' elif name.startswith(('lr.', 'sc.', 'amo')): return 'atomic' elif name.startswith(('mul', 'div', 'rem')): return 'muldiv' elif name.startswith(('fadd', 'fsub', 'fmul', 'fdiv', 'fmadd', 'fmsub', 'fnmadd', 'fnmsub', 'fmin', 'fmax', 'fsqrt', 'fld', 'fsd', 'flw', 'fsw', 'fcvt', 'fmv', 'feq', 'flt', 'fle', 'fclass', 'fsgnj')): return 'float' elif name.startswith(('fence', 'ecall', 'ebreak')): return 'fence' elif name.startswith(('andn', 'orn', 'xnor', 'clz', 'ctz', 'cpop', 'max', 'min', 'sext', 'zext', 'rol', 'ror', 'rev8', 'orc.b', 'bclr', 'bext', 'binv', 'bset', 'clmul', 'sh1add', 'sh2add', 'sh3add')): return 'bitmanip' elif name.startswith('c.'): return 'compressed' elif name.startswith('v'): return 'vector' else: return 'alu'