So, I found a solution in the most unlikely of places. The riscv organization on GitHub has a tool called
parse_opcodes, written in Python, that contains this block of bit pattern tuples:
Code:
arglut = {}
arglut['rd'] = (11,7)
arglut['rs1'] = (19,15)
arglut['rs2'] = (24,20)
arglut['rs3'] = (31,27)
arglut['aqrl'] = (26,25)
arglut['fm'] = (31,28)
arglut['pred'] = (27,24)
arglut['succ'] = (23,20)
arglut['rm'] = (14,12)
arglut['funct3'] = (14,12)
arglut['imm20'] = (31,12)
arglut['jimm20'] = (31,12)
arglut['imm12'] = (31,20)
arglut['imm12hi'] = (31,25)
arglut['bimm12hi'] = (31,25)
arglut['imm12lo'] = (11,7)
arglut['bimm12lo'] = (11,7)
arglut['zimm'] = (19,15)
arglut['shamt'] = (25,20)
arglut['shamtw'] = (24,20)
# for vectors
arglut['vd'] = (11,7)
arglut['vs3'] = (11,7)
arglut['vs1'] = (19,15)
arglut['vs2'] = (24,20)
arglut['vm'] = (25,25)
arglut['wd'] = (26,26)
arglut['amoop'] = (31,27)
arglut['nf'] = (31,29)
arglut['simm5'] = (19,15)
arglut['zimm11'] = (30,20)
Thus, this block in RV opcode format:
Code:
amoadd.w rd rs1 rs2 aqrl 31..29=0 28..27=0 14..12=2 6..2=0x0B 1..0=3
Translates into the binary:
Code:
00000aqrl rs2rs1 10rd 101111
The tricky part is ordering the bits properly. Its harder to follow the pattern when you have to insert other characters other than raw binary. But it works.
The only thing I'm curious about is how the different register types are encoded. For example, there are only 5 bits allocated to registers (excluding vector registers) so I'm assuming that the register number and exactly what register it is is determined by the opcode. Is that right?