29 A listing of standard RISC-V pseudoinstructions
Table 5. Pseudo Instructions
| Pseudoinstruction | Base Instruction(s) | Meaning | Comment |
|---|---|---|---|
| la rd, symbol | addi rd, rd, symbol[11:0] | Load address | With .option nopic (Default) |
| la rd, symbol | l{w|d} rd, symbol@GOT11:0 | Load address | With .option pic |
| lla rd, symbol | addi rd, rd, symbol[11:0] | Load local address | |
| lga rd, symbol | l{w|d} rd, symbol@GOT11:0 | Load global address | |
| l{b|h|w|d} rd, symbol | l{b|h|w|d} rd, symbol11:0 | Load global | |
| l{bu|hu|wu} rd, symbol | l{bu|hu|wu} rd, symbol11:0 | Load global, unsigned | |
| s{b|h|w|d} rd, symbol, rt | s{b|h|w|d} rd, symbol11:0 | Store global | |
| fl{h|w|d|q} rd, symbol, rt | fl{h|w|d|q} rd, symbol11:0 | Floating-point load global | |
| fs{h|w|d|q} rd, symbol, rt | fs{h|w|d|q} rd, symbol11:0 | Floating-point store global | |
| nop | addi x0, x0, 0 | No operation | |
| li rd, immediate | *Myriad sequences | Load immediate | |
| mv rd, rs | addi rd, rs, 0 | Copy register | |
| not rd, rs | xori rd, rs, -1 | Ones’ complement | |
| neg rd, rs | sub rd, x0, rs | Two’s complement | |
| negw rd, rs | subw rd, x0, rs | Two’s complement word | |
| sext.b rd, rs | srai rd, rd, XLEN - 8 | Sign extend byte | This is a single instruction when Zbb extension is available. |
| sext.h rd, rs | srai rd, rd, XLEN - 16 | Sign extend halfword | This is a single instruction when Zbb extension is available. |
| sext.w rd, rs | addiw rd, rs, 0 | Sign extend word | |
| zext.b rd, rs | andi rd, rs, 255 | Zero extend byte | |
| zext.h rd, rs | srli rd, rd, XLEN - 16 | Zero extend halfword | This is a single instruction when Zbb extension is available. |
| zext.w rd, rs | srli rd, rd, XLEN - 32 | Zero extend word | When Zba extension is not available |
| zext.w rd, rs | add.uw rd, rs, x0 | Zero extend word | When Zba extension is available |
| seqz rd, rs | sltiu rd, rs, 1 | Set if = zero | |
| snez rd, rs | sltu rd, x0, rs | Set if != zero | |
| sltz rd, rs | slt rd, rs, x0 | Set if < zero | |
| sgtz rd, rs | slt rd, x0, rs | Set if > zero | |
| sgt rd, rs, rt | slt rd, rt, rs | Set if > | |
| sgtu rd, rs, rt | sltu rd, rt, rs | Set if >, unsigned | |
| fmv.h frd, frs | fsgnj.h frd, frs, frs | Copy half-precision register | |
| fabs.h frd, frs | fsgnjx.h frd, frs, frs | Half-precision absolute value | |
| fneg.h frd, frs | fsgnjn.h frd, frs, frs | Half-precision negate | |
| fgt.h rd, frs, frt | flt.h rd, frt, frs | Half-precision > | |
| fge.h rd, frs, frt | fle.h rd, frt, frs | Half-precision >= | |
| fmv.s frd, frs | fsgnj.s frd, frs, frs | Copy single-precision register | |
| fabs.s frd, frs | fsgnjx.s frd, frs, frs | Single-precision absolute value | |
| fneg.s frd, frs | fsgnjn.s frd, frs, frs | Single-precision negate | |
| fgt.s rd, frs, frt | flt.s rd, frt, frs | Single-precision > | |
| fge.s rd, frs, frt | fle.s rd, frt, frs | Single-precision >= | |
| fmv.d frd, frs | fsgnj.d frd, frs, frs | Copy double-precision register | |
| fabs.d frd, frs | fsgnjx.d frd, frs, frs | Double-precision absolute value | |
| fneg.d frd, frs | fsgnjn.d frd, frs, frs | Double-precision negate | |
| fgt.d rd, frs, frt | flt.d rd, frt, frs | Double-precision > | |
| fge.d rd, frs, frt | fle.d rd, frt, frs | Double-precision >= | |
| fmv.q frd, frs | fsgnj.q frd, frs, frs | Copy quad-precision register | |
| fabs.q frd, frs | fsgnjx.q frd, frs, frs | Quad-precision absolute value | |
| fneg.q frd, frs | fsgnjn.q frd, frs, frs | Quad-precision negate | |
| fgt.q rd, frs, frt | flt.q rd, frt, frs | Quad-precision > | |
| fge.q rd, frs, frt | fle.q rd, frt, frs | Quad-precision >= | |
| beqz rs, offset | beq rs, x0, offset | Branch if = zero | |
| bnez rs, offset | bne rs, x0, offset | Branch if != zero | |
| blez rs, offset | bge x0, rs, offset | Branch if ≤ zero | |
| bgez rs, offset | bge rs, x0, offset | Branch if ≥ zero | |
| bltz rs, offset | blt rs, x0, offset | Branch if < zero | |
| bgtz rs, offset | blt x0, rs, offset | Branch if > zero | |
| bgt rs, rt, offset | blt rt, rs, offset | Branch if > | |
| ble rs, rt, offset | bge rt, rs, offset | Branch if ≤ | |
| bgtu rs, rt, offset | bltu rt, rs, offset | Branch if >, unsigned | |
| bleu rs, rt, offset | bgeu rt, rs, offset | Branch if ≤, unsigned | |
| j offset | jal x0, offset | Jump | |
| jump offset, rt | jalr x0, offset11:0 | Jump to far-away label | |
| jal offset | jal x1, offset | Jump and link | |
| jr rs | jalr x0, 0(rs) | Jump register | |
| jr offset(rs) | jalr x0, offset(rs) | Jump register plus offset | |
| jalr rs | jalr x1, 0(rs) | Jump and link register | |
| jalr offset(rs) | jalr x1, offset(rs) | Jump and link register plus offset | |
| jalr rd, rs | jalr rd, 0(rs) | Jump and link register | |
| ret | jalr x0, 0(x1) | Return from subroutine | |
| vfneg.v vd, vs | vfsgnjn.vv vd, vs, vs | Floating-point vector negate | |
| vfabs.v vd, vs | vfsgnjx.vv vd, vs, vs | Floating-point vector absolute value | |
| vmclr.m vd | vmxor.mm vd, vd, vd | Vector clear mask register | |
| vmfge.vv vd, va, vb, vm | vmfle.vv vd, vb, va, vm | Vector Floating-point >= | |
| vmfgt.vv vd, va, vb, vm | vmflt.vv vd, vb, va, vm | Vector Floating-point | |
| vmmv.m vd, vs | vmand.mm vd, vs, vs | Vector copy mask register | |
| vmnot.m vd, vs | vmnand.mm vd, vs, vs | Vector invert mask bits | |
| vmset.m vd | vmxnor.mm vd, vd, vd | Vector set all mask bits | |
| vmsge.vi vd, va, i, vm | vmsgt.vi vd, va, i-1, vm | Vector >= Immediate | When -15 ⇐ i ⇐ 16 |
| vmsgeu.vi vd, va, i, vm | vmsgtu.vi vd, va, i-1, vm | Vector >= Immediate, unsigned | When i != 0 and -15 ⇐ i ⇐ 16 |
| vmsgeu.vi vd, va, 0, vm | vmseq.vv vd, va, va, vm | Vector >= Immediate, unsigned | Sets active elements to true |
| vmsge.vv vd, va, vb, vm | vmsle.vv vd, vb, va, vm | Vector >= Vector | |
| vmsgeu.vv vd, va, vb, vm | vmsleu.vv vd, vb, va, vm | Vector >= Vector, unsigned | |
| vmsgt.vv vd, va, vb, vm | vmslt.vv vd, vb, va, vm | Vector > Vector | |
| vmsgtu.vv vd, va, vb, vm | vmsltu.vv vd, vb, va, vm | Vector > Vector, unsigned | |
| vmslt.vi vd, va, i, vm | vmsle.vi vd, va, i-1, vm | Vector < immediate | When -15 ⇐ i ⇐ 16 |
| vmsltu.vi vd, va, i, vm | vmsleu.vi vd, va, i-1, vm | Vector < immediate, unsigned | When i != 0 and -15 ⇐ i ⇐ 16 |
| vmsltu.vi vd, va, 0, vm | vmsne.vv vd, va, va, vm | Vector < immediate, unsigned | Sets active elements to false |
| vneg.v vd,vs | vrsub.vx vd,vs,x0 | Vector negate | |
| vnot.v vd,vs,vm | vxor.vi vd, vs, -1, vm | Vector not | |
| vncvt.x.x.w vd,vs,vm | vnsrl.wx vd,vs,x0,vm | Vector narrow convert element | |
| vwcvt.x.x.v vd,vs,vm | vwadd.vx vd,vs,x0,vm | Vector widen convert, integer-integer | |
| vwcvtu.x.x.v vd,vs,vm | vwaddu.vx vd,vs,x0,vm | Vector widen convert, integer-integer, unsigned | |
| vl1r.v v3, (rs1) | vl1re8.v v3, (rs1) | Equal to vl1re8.v | |
| vl2r.v v2, (rs1) | vl2re8.v v2, (rs1) | Equal to vl2re8.v | |
| vl4r.v v4, (rs1) | vl4re8.v v4, (rs1) | Equal to vl4re8.v | |
| vl8r.v v8, (rs1) | vl8re8.v v8, (rs1) | Equal to vl8re8.v | |
| vmsge{u}.vx vd, va, x | vmnand.mm vd, vd, vd | Vector >= scalar, unmasked | |
| vmsge{u}.vx vd, va, x, v0.t | vmxor.mm vd, vd, v0 | Vector >= scalar, masked | When vd≠v0 |
| vmsge{u}.vx vd, va, x, v0.t, vt | vmandn.mm vd, vd, vt | Vector >= scalar, masked | When vd=v0 |
| vmsge{u}.vx vd, va, x, v0.t, vt | vmor.mm vd, vt, vd | Vector >= scalar, masked | For any vd |
| call offset | jalr x1, offset11:0 | Call far-away subroutine | |
| call rt, offset | jalr rt, offset11:0 | Call far-away subroutine | |
| tail offset | jalr x0, offset11:0 | Tail call far-away subroutine | It will use x7 as scratch register when Zicfilp extension is available. |
| fence | fence iorw, iorw | Fence on all memory and I/O | |
| pause | fence w, 0 | PAUSE hint |