sail-riscv
sail-riscv copied to clipboard
Bad disassembly for RVC HINTs
RVC HINTs are disassembled with names like c.nop.hint.<imm>
rather than the mnemonics used by actual (dis)assemblers (which are generally just whatever the non-HINT version would be in the case of using a zero register, but some exceptions for things like c.nop
, which ends up taking an additional immediate argument when non-zero, and c.s{ll,rl,ra}i
with a zero immediate, which end up being the strange c.s{ll,rl,ra}i64
with no immediate).
See discussion in #31.
Moving the discussion from #324 here... (I may be showing my ignorance, so bear with me.)
Taking one example, c.li
... The definition of the instruction (assembly) is:
mapping clause assembly = C_LI(imm, rd)
if rd != zreg
<-> "c.li" ^ spc() ^ reg_name(rd) ^ sep() ^ hex_bits_6(imm)
if rd != zreg
The hint equivalent (and I agree it is strange):
mapping clause assembly = C_LI_HINT(imm)
<-> "c.li.hint." ^ hex_bits_6(imm)
Does it make sense for the latter to be something more like:
mapping clause assembly = C_LI(imm, rd)
if rd == zreg
<-> "c.li" ^ spc() ^ hex_bits_6(imm)
if rd == zreg
?
It uses the correct mnemonic and it's mutually exclusive with the actual instruction due to the condition. Does the presence of rd
break something?
Does it make sense for the latter to be something more like:
mapping clause assembly = C_LI(imm, rd) if rd == zreg <-> "c.li" ^ spc() ^ hex_bits_6(imm)
if rd == zreg ?
Well the assembly needs to actually include rd...
Note that LLVM will treat it as c.li zero, imm
, i.e. the "obvious" mapping. I assume binutils is similar.
Is:
mapping clause assembly = C_LI_HINT(imm)
<-> "c.li" ^ spc() ^ "zero" ^ sep() ^ hex_bits_6(imm)
what you want?
Better use reg_name(zreg)
rather than hard-coding register names everywhere