Introduction
Assemblers and disassemblers write many common instructions under shorter names. With the option
“Pseudo-instructions: on” (the default) the explorer writes these for single 32-bit instructions, as
llvm-objdump does; with it off, every instruction is written as encoded. The instruction details
(the decoded fields and the link to the manual page) always name the encoded instruction. A 16-bit instruction keeps its
c. name, except c.jr ra, which is written ret. Assembler macros that expand
to two instructions (call, tail, la, a li of a large value) are not
recognised: the disassembler shows the auipc and the jalr or addi
separately.
Integer
| Written as | Is | When |
|---|---|---|
nop | addi x0, x0, 0 | |
li rd, imm | addi rd, x0, imm | rs1 = x0 (a 12-bit immediate; larger ones are two instructions) |
mv rd, rs | addi rd, rs, 0 | imm = 0, rs ≠ x0 |
not rd, rs | xori rd, rs, -1 | |
neg rd, rs, negw rd, rs | sub rd, x0, rs, subw rd, x0, rs | |
sext.w rd, rs | addiw rd, rs, 0 | RV64 |
seqz rd, rs | sltiu rd, rs, 1 | |
snez rd, rs | sltu rd, x0, rs | |
sltz rd, rs, sgtz rd, rs | slt rd, rs, x0, slt rd, x0, rs | |
zext.b rd, rs | andi rd, rs, 255 | |
zext.w rd, rs | add.uw rd, rs, x0 | Zba |
zext.h rd, rs | pack rd, rs, x0 (RV32; RV64 has its own encoding) | Zbb |
Branches, jumps and returns
| Written as | Is |
|---|---|
beqz rs, offset, bnez rs, offset | beq rs, x0, offset, bne rs, x0, offset |
blez rs, offset, bgez rs, offset | bge x0, rs, offset, bge rs, x0, offset |
bltz rs, offset, bgtz rs, offset | blt rs, x0, offset, blt x0, rs, offset |
j offset | jal x0, offset |
jal offset | jal ra, offset |
jr rs | jalr x0, 0(rs) |
jalr rs | jalr ra, 0(rs) |
ret | jalr x0, 0(ra) (and c.jr ra) |
The reversed comparisons bgt, ble, bgtu, bleu are assembler
names only: the explorer writes the encoded blt, bge, bltu,
bgeu.
CSR access
| Written as | Is |
|---|---|
csrr rd, csr | csrrs rd, csr, x0 |
csrw csr, rs | csrrw x0, csr, rs |
csrs csr, rs, csrc csr, rs | csrrs x0, csr, rs, csrrc x0, csr, rs |
csrwi csr, imm, csrsi, csrci | csrrwi x0, csr, imm, csrrsi x0, …, csrrci x0, … |
rdcycle rd, rdtime rd, rdinstret rd (and …h on RV32) | csrrs rd, cycle, x0 and the like |
frcsr rd, frrm rd, frflags rd | csrrs rd, fcsr|frm|fflags, x0 |
fscsr rs, fsrm rs, fsflags rs (and with an rd) | csrrw rd, fcsr|frm|fflags, rs |
fsrmi imm, fsflagsi imm | csrrwi rd, frm|fflags, imm |
unimp | csrrw x0, cycle, x0 (0xc0001073), the 32-bit illegal instruction |
Other
| Written as | Is |
|---|---|
fence | fence iorw, iorw |
fmv.s, fneg.s, fabs.s (and .d, .h, .q) | fsgnj.s, fsgnjn.s, fsgnjx.s with both source registers equal |
vneg.v, vnot.v, vfneg.v, vfabs.v, vncvt.x.x.w, vwcvt.x.x.v, vwcvtu.x.x.v, vmmv.m, vmnot.m, vmclr.m, vmset.m, vl1r.v to vl8r.v | vrsub.vx with x0, vxor.vi with −1, vfsgnjn.vv and vfsgnjx.vv with equal sources, vnsrl.wx and vwadd.vx, vwaddu.vx with x0, vmand.mm, vmnand.mm with equal sources, vmxor.mm, vmxnor.mm with all three registers equal, vl1re8.v to vl8re8.v |
jr offset(rs), jalr offset(rs), jalr rd, rs | jalr x0, offset(rs), jalr ra, offset(rs), jalr rd, 0(rs) |
With the rounding mode: when pseudo-instructions are on, dyn is left out; when off, it is written, as
llvm-mc -M no-aliases does. A conversion that cannot round (fcvt.d.s, fcvt.d.w)
leaves out rne in both.