RISC-V instructions

Instructions by category

Arithmetic:add addi addiw addw amoadd.d amoadd.w amomax.d amomaxu.d amomaxu.w amomax.w amomin.d amominu.d amominu.w amomin.w div divu divuw divw (fabs.d) (fabs.s) fadd.d fadd.s fdiv.d fdiv.s fmadd.d fmadd.s fmax.d fmax.s fmin.d fmin.s fmsub.d fmsub.s fmul.d fmul.s (fneg.d) (fneg.s) fnmadd.d fnmadd.s fnmsub.d fnmsub.s fsqrt.d fsqrt.s fsub.d fsub.s mul mulh mulhsu mulhu mulw (neg) (negw) rem remu remuw remw sub subw
Logic:amoand.d amoand.w amoor.d amoor.w amoxor.d amoxor.w and andi (not) or ori xor xori
Branch:beq (beqz) bge bgeu (bgez) (bgt) (bgtu) (bgtz) (ble) (bleu) (blez) blt bltu (bltz) bne (bnez)
Jump:(call) (j) jal jalr (jr) (ret) (tail)
Memory:fence fence.i fld flw fsd fsw lb lbu ld lh lhu lr.d lr.w lw lwu sb sc.d sc.w sd sh sw
Convert:fcvt.d.l fcvt.d.lu fcvt.d.s fcvt.d.w fcvt.d.wu fcvt.l.d fcvt.l.s fcvt.lu.d fcvt.lu.s fcvt.s.d fcvt.s.l fcvt.s.lu fcvt.s.w fcvt.s.wu fcvt.w.d fcvt.w.s fcvt.wu.d fcvt.wu.s
Conditional:feq.d feq.s fle.d fle.s flt.d flt.s (seqz) (sgtz) slt slti sltiu sltu (sltz) (snez)
Uncategorized:amoswap.d amoswap.w auipc csrrc csrrci csrrs csrrsi csrrw csrrwi ebreak ecall fclass.d fclass.s (fmv.d) fmv.d.x (fmv.s) fmv.w.x fmv.x.d fmv.x.w fsgnj.d fsgnjn.d fsgnjn.s fsgnj.s fsgnjx.d fsgnjx.s (la) (li) lui (mv) (nop) (sext.w) sll slli slliw sllw sra srai sraiw sraw srl srli srliw srlw

Explanations

TermMeaning
immImmediate integer value
pcProgram counter
rdDestination integer register
fdDestination floating-point register
rs*Source integer register
fs*Source floating-point register
sext(n)Sign extend n
1ext(n)1-extend n; fill upper bits with ones; called "nan-boxing" when done with floating-point values
x[n]Integer register number n
f[n]Floating-point register number n
M[n]Memory at address n
<sLess than (signed)
<uLess than (unsigned)
^Bitwise Exclusive OR
|Bitwise OR
&Bitwise AND
~Bitwise NOT
<<Logical bitshift left
>>uLogical bitshift right
>>sArithmetic bitshift right
XLENThe size of a register in bits (32 on RV32, 64 on RV64)
XHIThe index of the highest bit (XLEN - 1)
DXHIThe index of the highest bit of a double sized register (XLEN * 2 - 1)
byte8-bit number
halfword16-bit number
word32-bit number
doubleword64-bit number

Some of the instructions are called "pseudoinstructions". They are not real instructions for the processor with their own encoding, but a syntax that your assembler may compile into one or more real instructions. The reason that they have been defined is probably to make assembly code easier to read and write. An example of a pseudoinstruction is "j" to jump, which is defined as a special use of "jal" that doesn't link.

Floating-point instructions have a field called "rm". This field selects the rounding mode. Possible values are:

ValueNameDescription
000RNERound to nearest, ties to even.
001RTZRound towards zero.
010RDNRound down.
011RUPRound up.
100RMMRound to nearest, ties to max magnitude.
101Invalid.
110Invalid.
111DYNDynamic; use rounding mode specified in rounding mode register.

Atomic instructions have the fields "aq" and "rl". They work like the "fence" instruction. If "aq" is 1 then no memory operation following the atomic instruction can be observed before the atomic instruction by any hart. If "rl" is 1 then no memory operation before the atomic instruction can be observed after the atomic instruction by any hart.

For full specifications, see https://riscv.org/technical/specifications/.

Instructions

RV32I, RV64I

add rd, rs1, rs2

Add. Add rs1 and rs2 and put the result in rd. Arithmetic overflow is ignored.

x[rd] = x[rs1] + x[rs2]
31 2524 2019 1514 1211 76 0
0000000rs2rs1000rd0110011
755357

RV32I, RV64I

addi rd, rs1, imm

Add immediate. Add rs1 and imm and put the result in rd. Arithmetic overflow is ignored.

x[rd] = x[rs1] + sext(imm)
31 2019 1514 1211 76 0
imm[11:0]rs1000rd0010011
125357

RV64I

addiw rd, rs1, imm

Add word immediate. Add rs1 and imm and put the result in rd. Arithmetic overflow is ignored.

x[rd] = sext((x[rs1] + sext(imm))[31:0])
31 2019 1514 1211 76 0
imm[11:0]rs1000rd0011011
125357

RV64I

addw rd, rs1, rs2

Add word. Add rs1 and rs2 and put the result in rd. Arithmetic overflow is ignored.

x[rd] = sext((x[rs1] + x[rs2])[31:0])
31 2524 2019 1514 1211 76 0
0000000rs2rs1000rd0111011
755357

RV64A

amoadd.d rd, rs2, (rs1)

Atomic add doubleword. Atomically load the value at address rs1 into rd, add rd and rs2 and put the result in memory at address rs1. Arithmetic overflow is ignored.

The address in rs1 must be aligned to 8 bytes.

x[rd] = M[x[rs1]][63:0]
M[x[rs1]] = (x[rd] + x[rs2])[63:0]
31 2524 2019 1514 1211 76 0
00000, aq, rlrs2rs1011rd0101111
755357

Related: add


RV32A, RV64A

amoadd.w rd, rs2, (rs1)

Atomic add word. Atomically load the value at address rs1 into rd, add rd and rs2 and put the result in memory at address rs1. Arithmetic overflow is ignored.

The address in rs1 must be aligned to 4 bytes.

x[rd] = sext(M[x[rs1]][31:0])
M[x[rs1]] = (M[x[rs1]][31:0] + x[rs2])[31:0]
31 2524 2019 1514 1211 76 0
00000, aq, rlrs2rs1010rd0101111
755357

Related: addw


RV64A

amoand.d rd, rs2, (rs1)

Atomic AND doubleword. Atomically load the value at address rs1 into rd, calculate the bitwise AND on rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 8 bytes.

x[rd] = sext(M[x[rs1]][63:0])
M[x[rs1]] = (M[x[rs1]][63:0] & x[rs2])[63:0]
31 2524 2019 1514 1211 76 0
01100, aq, rlrs2rs1011rd0101111
755357

Related: and


RV32A, RV64A

amoand.w rd, rs2, (rs1)

Atomic AND word. Atomically load the value at address rs1 into rd, calculate the bitwise AND on rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 4 bytes.

x[rd] = sext(M[x[rs1]][31:0])
M[x[rs1]] = (M[x[rs1]][31:0] & x[rs2])[31:0]
31 2524 2019 1514 1211 76 0
01100, aq, rlrs2rs1010rd0101111
755357

Related: and


RV64A

amomax.d rd, rs2, (rs1)

Atomic maximum doubleword. Atomically load the value at address rs1 into rd, calculate the maximum value of rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 8 bytes.

x[rd] = sext(M[x[rs1]][63:0])
M[x[rs1]] = max(M[x[rs1]][63:0], x[rs2])[63:0]
31 2524 2019 1514 1211 76 0
10100, aq, rlrs2rs1011rd0101111
755357

RV64A

amomaxu.d rd, rs2, (rs1)

Atomic unsigned maximum word. Atomically load the value at address rs1 into rd, calculate the unsigned maximum value of rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 8 bytes.

x[rd] = sext(M[x[rs1]][63:0])
M[x[rs1]] = maxu(M[x[rs1]][63:0], x[rs2])[63:0]
31 2524 2019 1514 1211 76 0
11100, aq, rlrs2rs1011rd0101111
755357

RV32A, RV64A

amomaxu.w rd, rs2, (rs1)

Atomic unsigned maximum word. Atomically load the value at address rs1 into rd, calculate the unsigned maximum value of rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 4 bytes.

x[rd] = sext(M[x[rs1]][31:0])
M[x[rs1]] = maxu(M[x[rs1]][31:0], x[rs2])[31:0]
31 2524 2019 1514 1211 76 0
11100, aq, rlrs2rs1010rd0101111
755357

RV32A, RV64A

amomax.w rd, rs2, (rs1)

Atomic maximum word. Atomically load the value at address rs1 into rd, calculate the maximum value of rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 4 bytes.

x[rd] = sext(M[x[rs1]][31:0])
M[x[rs1]] = max(M[x[rs1]][31:0], x[rs2])[31:0]
31 2524 2019 1514 1211 76 0
10100, aq, rlrs2rs1010rd0101111
755357

RV64A

amomin.d rd, rs2, (rs1)

Atomic minimum doubleword. Atomically load the value at address rs1 into rd, calculate the minimum value of rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 8 bytes.

x[rd] = sext(M[x[rs1]][63:0])
M[x[rs1]] = min(M[x[rs1]][63:0], x[rs2])[63:0]
31 2524 2019 1514 1211 76 0
10000, aq, rlrs2rs1011rd0101111
755357

RV64A

amominu.d rd, rs2, (rs1)

Atomic unsigned minimum word. Atomically load the value at address rs1 into rd, calculate the unsigned minimum value of rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 8 bytes.

x[rd] = sext(M[x[rs1]][63:0])
M[x[rs1]] = minu(M[x[rs1]][63:0], x[rs2])[63:0]
31 2524 2019 1514 1211 76 0
11000, aq, rlrs2rs1011rd0101111
755357

RV32A, RV64A

amominu.w rd, rs2, (rs1)

Atomic unsigned minimum word. Atomically load the value at address rs1 into rd, calculate the unsigned minimum value of rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 4 bytes.

x[rd] = sext(M[x[rs1]][31:0])
M[x[rs1]] = minu(M[x[rs1]][31:0], x[rs2])[31:0]
31 2524 2019 1514 1211 76 0
11000, aq, rlrs2rs1010rd0101111
755357

RV32A, RV64A

amomin.w rd, rs2, (rs1)

Atomic minimum word. Atomically load the value at address rs1 into rd, calculate the minimum value of rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 4 bytes.

x[rd] = sext(M[x[rs1]][31:0])
M[x[rs1]] = min(M[x[rs1]][31:0], x[rs2])[31:0]
31 2524 2019 1514 1211 76 0
10000, aq, rlrs2rs1010rd0101111
755357

RV64A

amoor.d rd, rs2, (rs1)

Atomic OR doubleword. Atomically load the value at address rs1 into rd, calculate the bitwise OR on rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 8 bytes.

x[rd] = sext(M[x[rs1]][63:0])
M[x[rs1]] = (M[x[rs1]][63:0] | x[rs2])[63:0]
31 2524 2019 1514 1211 76 0
01000, aq, rlrs2rs1011rd0101111
755357

Related: or


RV32A, RV64A

amoor.w rd, rs2, (rs1)

Atomic OR word. Atomically load the value at address rs1 into rd, calculate the bitwise OR on rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 4 bytes.

x[rd] = sext(M[x[rs1]][31:0])
M[x[rs1]] = (M[x[rs1]][31:0] | x[rs2])[31:0]
31 2524 2019 1514 1211 76 0
01000, aq, rlrs2rs1010rd0101111
755357

Related: or


RV64A

amoswap.d rd, rs2, (rs1)

Atomic swap doubleword. Atomically load the value at address rs1 into rd and write the value of rs2 to address rs1.

The address in rs1 must be aligned to 8 bytes.

x[rd] = sext(M[x[rs1]][63:0])
M[x[rs1]] = x[rs2][63:0]
31 2524 2019 1514 1211 76 0
00001, aq, rlrs2rs1011rd0101111
755357

RV32A, RV64A

amoswap.w rd, rs2, (rs1)

Atomic swap word. Atomically load the value at address rs1 into rd and write the value of rs2 to address rs1.

The address in rs1 must be aligned to 4 bytes.

x[rd] = sext(M[x[rs1]][31:0])
M[x[rs1]] = x[rs2][31:0]
31 2524 2019 1514 1211 76 0
00001, aq, rlrs2rs1010rd0101111
755357

RV64A

amoxor.d rd, rs2, (rs1)

Atomic XOR doubleword. Atomically load the value at address rs1 into rd, calculate the bitwise XOR on rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 8 bytes.

x[rd] = sext(M[x[rs1]][63:0])
M[x[rs1]] = (M[x[rs1]][63:0] ^ x[rs2])[63:0]
31 2524 2019 1514 1211 76 0
00100, aq, rlrs2rs1011rd0101111
755357

Related: xor


RV32A, RV64A

amoxor.w rd, rs2, (rs1)

Atomic XOR word. Atomically load the value at address rs1 into rd, calculate the bitwise XOR on rd and rs2 and put the result in memory at address rs1.

The address in rs1 must be aligned to 4 bytes.

x[rd] = sext(M[x[rs1]][31:0])
M[x[rs1]] = (M[x[rs1]][31:0] ^ x[rs2])[31:0]
31 2524 2019 1514 1211 76 0
00100, aq, rlrs2rs1010rd0101111
755357

Related: xor


RV32I, RV64I

and rd, rs1, rs2

AND. Calculate bitwise AND on rs1 and rs2 and put the result in rd.

x[rd] = x[rs1] & x[rs2]
31 2524 2019 1514 1211 76 0
0000000rs2rs1111rd0110011
755357

RV32I, RV64I

andi rd, rs1, imm

AND immediate. Calculate bitwise AND on rs1 and imm and put the result in rd.

x[rd] = x[rs1] & sext(imm)
31 2019 1514 1211 76 0
imm[11:0]rs1111rd0010011
125357

RV32I, RV64I

auipc rd, imm[31:12]

Add upper immediate to pc. Can be used to build addresses relative to program counter. Add imm (with lower 12 bits = 0) and pc and put the result in rd.

x[rd] = pc + sext(imm[31:12] << 12)
31 1211 76 0
imm[31:12]rd0010111
2057

Related: lui


RV32I, RV64I

beq rs1, rs2, imm

Branch if =. Add imm (multiple of 2) to pc if rs1 and rs2 are equal.

if (rs1 == rs2) pc += sext(imm)
31 2524 2019 1514 1211 76 0
imm[12,10:5]rs2rs1000imm[4:1,11]1100011
755357

beqz rs1, imm

Branch if = zero. Pseudoinstruction.

beq rs1, x0, imm

RV32I, RV64I

bge rs1, rs2, imm

Branch if ≥. Add imm (multiple of 2) to pc if rs1 is greater than (signed) or equal to rs2.

if (rs1 ≥s rs2) pc += sext(imm)
31 2524 2019 1514 1211 76 0
imm[12,10:5]rs2rs1101imm[4:1,11]1100011
755357

RV32I, RV64I

bgeu rs1, rs2, imm

Branch if ≥, unsigned. Add imm (multiple of 2) to pc if rs1 is greater than (unsigned) or equal to rs2.

if (rs1 ≥u rs2) pc += sext(imm)
31 2524 2019 1514 1211 76 0
imm[12,10:5]rs2rs1111imm[4:1,11]1100011
755357

bgez rs1, imm

Branch if ≥ zero. Pseudoinstruction.

bge rs1, x0, imm

bgt rs1, rs2, imm

Branch if >. Pseudoinstruction.

blt rs2, rs1, imm

bgtu rs1, rs2, imm

Branch if >, unsigned. Pseudoinstruction.

bltu rs2, rs1, imm

bgtz rs1, imm

Branch if > zero. Pseudoinstruction.

blt x0, rs1, imm

ble rs1, rs2, imm

Branch if ≤. Pseudoinstruction.

bge rs2, rs1, imm

bleu rs1, rs2, imm

Branch if ≤, unsigned. Pseudoinstruction.

bgeu rs2, rs1, imm

blez rs, imm

Branch if ≤ zero. Pseudoinstruction.

bge x0, rs, imm

RV32I, RV64I

blt rs1, rs2, imm

Branch if <. Add imm (multiple of 2) to pc if rs1 is less than (signed) rs2.

if (rs1 <s rs2) pc += sext(imm)
31 2524 2019 1514 1211 76 0
imm[12,10:5]rs2rs1100imm[4:1,11]1100011
755357

RV32I, RV64I

bltu rs1, rs2, imm

Branch if <, unsigned. Add imm (multiple of 2) to pc if rs1 is less than (unsigned) rs2.

if (rs1 <u rs2) pc += sext(imm)
31 2524 2019 1514 1211 76 0
imm[12,10:5]rs2rs1110imm[4:1,11]1100011
755357

bltz rs, imm

Branch if < zero. Pseudoinstruction.

blt rs, x0, imm

RV32I, RV64I

bne rs1, rs2, imm

Branch if ≠. Add imm (multiple of 2) to pc if rs1 and rs2 are not equal.

if (rs1 ≠ rs2) pc += sext(imm)
31 2524 2019 1514 1211 76 0
imm[12,10:5]rs2rs1001imm[4:1,11]1100011
755357

bnez rs, imm

Branch if ≠ zero. Pseudoinstruction.

bne rs, x0, imm

call imm

Call far-away subroutine. Pseudoinstruction.

auipc x6, imm[31:12]
jalr x1, imm[11:0](x6)

Related: tail


RV32I, RV64I

csrrc rd csr rs1

Control and status register read and clear. Atomically writes the old value of csr to rd and clears the csr bits that are set in rs1. Unwritable bits in csr are unaffected.

If rs1 is x0 then csr is not written to and no side effects from writing to it will occur (this is not the same when rs1 is another register that holds value 0).

t = CSRs[csr]
CSRs[csr] = t & ∼x[rs1]
x[rd] = t
31 2019 1514 1211 76 0
csrrs1011rd1110011
125357

RV32I, RV64I

csrrci rd csr imm[4:0]

Control and status register read and clear immediate. Atomically writes the old value of csr to rd and clears the csr bits that are set in imm. Unwritable bits in csr are unaffected.

If imm is 0 then csr is not written to and no side effects from writing to it will occur.

t = CSRs[csr]
CSRs[csr] = t & ∼imm
x[rd] = t
31 2019 1514 1211 76 0
csrimm111rd1110011
125357

RV32I, RV64I

csrrs rd, csr, rs1

Control and status register read and set. Atomically writes the old value of csr to rd and sets the csr bits that are set in rs1. Unwritable bits in csr are unaffected.

If rs1 is x0 then csr is not written to and no side effects from writing to it will occur (this is not the same when rs1 is another register that holds value 0).

t = CSRs[csr]
CSRs[csr] = t | x[rs1]
x[rd] = t
31 2019 1514 1211 76 0
csrrs1010rd1110011
125357

RV32I, RV64I

csrrsi rd, csr, imm[4:0]

Control and status register read and set immediate. Atomically writes the old value of csr to rd and sets the csr bits that are set in imm. Unwritable bits in csr are unaffected.

If imm is 0 then csr is not written to and no side effects from writing to it will occur.

t = CSRs[csr]
CSRs[csr] = t | imm
x[rd] = t
31 2019 1514 1211 76 0
csrimm110rd1110011
125357

RV32I, RV64I

csrrw rd, csr, rs1

Control and status register read and write. Atomically writes the old value of csr to rd and rs1 to csr.

If rd is x0 then csr is not read and no side effects from reading it will occur.

t = CSRs[csr]
CSRs[csr] = x[rs1]
x[rd] = t
31 2019 1514 1211 76 0
csrrs1001rd1110011
125357

RV32I, RV64I

csrrwi rd, csr, imm[4:0]

Control and status register read and write immediate. Atomically writes the old value of csr to rd and imm to csr.

If rd is x0 then csr is not read and no side effects from reading it will occur.

t = CSRs[csr]
CSRs[csr] = imm
x[rd] = t
31 2019 1514 1211 76 0
csrimm101rd1110011
125357

RV32M, RV64M

div rd, rs1, rs2

Divide. Divide rs1 by rs2 and put the result (rounded towards zero) in rd.

x[rd] = x[rs1] /s x[rs2]
31 2524 2019 1514 1211 76 0
0000001rs2rs1100rd0110011
755357

Related: rem


RV32M, RV64M

divu rd, rs1, rs2

Divide unsigned. Divide unsigned rs1 by unsigned rs2 and put the result (rounded towards zero) in rd.

x[rd] = x[rs1] /u x[rs2]
31 2524 2019 1514 1211 76 0
0000001rs2rs1101rd0110011
755357

Related: remu


RV64M

divuw rd, rs1, rs2

Divide unsigned word. Divide the lower 32 bits of unsigned rs1 by the lower 32 bits of unsigned rs2 and put the result (rounded towards zero) in rd.

x[rd] = x[rs1][31:0] /u x[rs2][31:0]
31 2524 2019 1514 1211 76 0
0000001rs2rs1101rd0111011
755357

Related: remuw


RV64M

divw rd, rs1, rs2

Divide word. Divide the lower 32 bits of rs1 by the lower 32 bits of rs2 and put the result (rounded towards zero) in rd.

x[rd] = x[rs1][31:0] /s x[rs2][31:0]
31 2524 2019 1514 1211 76 0
0000001rs2rs1100rd0111011
755357

Related: remw


RV32I, RV64I

ebreak

Environment breakpoint. Used by debuggers to cause control to be transferred back to the debugger.

RaiseException(Breakpoint)
31 2019 1514 1211 76 0
00000000000100000000000001110011
125357

RV32I, RV64I

ecall

Environment call. Make a request to the supporting execution environment (usually the operating system).

RaiseException(EnvironmentCall)
31 2019 1514 1211 76 0
00000000000000000000000001110011
125357

fabs.d fd, fs

Double-precision absolute value. Pseudoinstruction.

fsgnjx.d fd, fs, fs

fabs.s fd, fs

Single-precision absolute value. Pseudoinstruction.

fsgnjx.s fd, fs, fs

RV32D, RV64D

fadd.d fd, fs1, fs2

Add double-precision floating-point. Calculate fs1+fs2 and put the result in fd.

The rm field is rounding mode.

f[fd] = f[fs1] + f[fs2]
31 2524 2019 1514 1211 76 0
0000001fs2fs1rmfd1010011
755357

RV32F, RV64F

fadd.s fd, fs1, fs2

Add single-precision floating-point. Calculate fs1+fs2 and put the result in fd.

The rm field is rounding mode.

f[fd] = f[fs1] + f[fs2]
31 2524 2019 1514 1211 76 0
0000000fs2fs1rmfd1010011
755357

RV32D, RV64D

fclass.d rd, fs

Classify double-precision floating-point. Set flags in rd depending on the properties of fs. Other bits are set to 0.

rd bitMeaning
0fs is -infinity
1fs is a negative normal number
2fs is a negative subnormal number
3fs is -0
4fs is +0
5fs is a positive subnormal number
6fs is a positive normal number
7fs is +infinity
8fs is a signaling NaN
9fs is a quiet NaN
r[rd] = Classify(f[fs])
31 2524 2019 1514 1211 76 0
111000100000fs001rd1010011
755357

RV32F, RV64F

fclass.s rd, fs

Classify single-precision floating-point. Set flags in rd depending on the properties of fs. Other bits are set to 0.

rd bitMeaning
0fs is -infinity
1fs is a negative normal number
2fs is a negative subnormal number
3fs is -0
4fs is +0
5fs is a positive subnormal number
6fs is a positive normal number
7fs is +infinity
8fs is a signaling NaN
9fs is a quiet NaN
r[rd] = Classify(f[fs])
31 2524 2019 1514 1211 76 0
111000000000fs001rd1010011
755357

RV64D

fcvt.d.l fd, rs1

Convert 64-bit integer to double-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(i64_to_f32(x[rs1]))
31 2524 2019 1514 1211 76 0
110100100010rs1rmfd1010011
755357

RV64D

fcvt.d.lu fd, rs1

Convert 64-bit unsigned integer to double-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(u64_to_f32(x[rs1]))
31 2524 2019 1514 1211 76 0
110100100011rs1rmfd1010011
755357

RV64D

fcvt.d.s fd, fs1

Convert single-precision to double-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(f32_to_f64(f[fs1][31:0]))
31 2524 2019 1514 1211 76 0
010000100000fs1rmfd1010011
755357

Related: fcvt.s.d


RV32D, RV64D

fcvt.d.w fd, rs1

Convert 32-bit integer to double-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(i32_to_f32(x[rs1][31:0]))
31 2524 2019 1514 1211 76 0
110100100000rs1rmfd1010011
755357

RV32D, RV64D

fcvt.d.wu fd, rs1

Convert 32-bit unsigned integer to double-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(u32_to_f32(x[rs1][31:0]))
31 2524 2019 1514 1211 76 0
110100100001rs1rmfd1010011
755357

RV64D

fcvt.l.d rd, fs1

Convert double-precision floating-point to 64-bit integer.

Out of bounds results are clamped between minimum and maximum 64-bit signed integer values and the invalid flag is set. NaN counts as positive infinity.

The rm field is rounding mode.

x[rd] = f64_to_i64(f[fs1])
31 2524 2019 1514 1211 76 0
110000100010fs1rmrd1010011
755357

RV64F

fcvt.l.s rd, fs1

Convert single-precision floating-point to 64-bit integer.

Out of bounds results are clamped between minimum and maximum 64-bit signed integer values and the invalid flag is set. NaN counts as positive infinity.

The rm field is rounding mode.

x[rd] = f32_to_i64(f[fs1])
31 2524 2019 1514 1211 76 0
110000000010fs1rmrd1010011
755357

RV64D

fcvt.lu.d rd, fs1

Convert double-precision floating-point to unsigned 64-bit integer.

Out of bounds results are clamped between minimum and maximum 64-bit unsigned integer values and the invalid flag is set. NaN counts as positive infinity.

The rm field is rounding mode.

x[rd] = f32_to_u64(f[fs1])
31 2524 2019 1514 1211 76 0
110000100011fs1rmrd1010011
755357

RV64F

fcvt.lu.s rd, fs1

Convert single-precision floating-point to unsigned 64-bit integer.

Out of bounds results are clamped between minimum and maximum 64-bit unsigned integer values and the invalid flag is set. NaN counts as positive infinity.

The rm field is rounding mode.

x[rd] = f32_to_u64(f[fs1])
31 2524 2019 1514 1211 76 0
110000000011fs1rmrd1010011
755357

RV64D

fcvt.s.d fd, fs1

Convert double-precision to single-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(f64_to_f632(f[fs1][63:0]))
31 2524 2019 1514 1211 76 0
010000000001fs1rmfd1010011
755357

Related: fcvt.d.s


RV64F

fcvt.s.l fd, rs1

Convert 64-bit integer to single-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(i64_to_f32(x[rs1]))
31 2524 2019 1514 1211 76 0
110100000010rs1rmfd1010011
755357

RV64F

fcvt.s.lu fd, rs1

Convert 64-bit unsigned integer to single-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(u64_to_f32(x[rs1]))
31 2524 2019 1514 1211 76 0
110100000011rs1rmfd1010011
755357

RV32F, RV64F

fcvt.s.w fd, rs1

Convert 32-bit integer to single-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(i32_to_f32(x[rs1][31:0]))
31 2524 2019 1514 1211 76 0
110100000000rs1rmfd1010011
755357

RV32F, RV64F

fcvt.s.wu fd, rs1

Convert 32-bit unsigned integer to single-precision floating-point.

The rm field is rounding mode.

f[fd] = 1ext(u32_to_f32(x[rs1][31:0]))
31 2524 2019 1514 1211 76 0
110100000001rs1rmfd1010011
755357

RV32D, RV64D

fcvt.w.d rd, fs1

Convert double-precision floating-point to 32-bit integer.

Out of bounds results are clamped between minimum and maximum 32-bit signed integer values and the invalid flag is set. NaN counts as positive infinity.

The rm field is rounding mode.

x[rd] = sext(f64_to_i32(f[fs1]))
31 2524 2019 1514 1211 76 0
110000100000fs1rmrd1010011
755357

RV32F, RV64F

fcvt.w.s rd, fs1

Convert single-precision floating-point to 32-bit integer.

Out of bounds results are clamped between minimum and maximum 32-bit signed integer values and the invalid flag is set. NaN counts as positive infinity.

The rm field is rounding mode.

x[rd] = sext(f32_to_i32(f[fs1]))
31 2524 2019 1514 1211 76 0
110000000000fs1rmrd1010011
755357

RV32D, RV64D

fcvt.wu.d rd, fs1

Convert double-precision floating-point to unsigned 32-bit integer.

Out of bounds results are clamped between minimum and maximum 32-bit unsigned integer values and the invalid flag is set. NaN counts as positive infinity.

The rm field is rounding mode.

x[rd] = sext(f32_to_u32(f[fs1]))
31 2524 2019 1514 1211 76 0
110000100001fs1rmrd1010011
755357

RV32F, RV64F

fcvt.wu.s rd, fs1

Convert single-precision floating-point to unsigned 32-bit integer.

Out of bounds results are clamped between minimum and maximum 32-bit unsigned integer values and the invalid flag is set. NaN counts as positive infinity.

The rm field is rounding mode.

x[rd] = sext(f32_to_u32(f[fs1]))
31 2524 2019 1514 1211 76 0
110000000001fs1rmrd1010011
755357

RV32D, RV64D

fdiv.d fd, fs1, fs2

Divide double-precision floating-point. Calculate fs1/fs2 and put the result in fd.

The rm field is rounding mode.

f[fd] = f[fs1] / f[fs2]
31 2524 2019 1514 1211 76 0
0001101fs2fs1rmfd1010011
755357

RV32F, RV64F

fdiv.s fd, fs1, fs2

Divide single-precision floating-point. Calculate fs1/fs2 and put the result in fd.

The rm field is rounding mode.

f[fd] = f[fs1] / f[fs2]
31 2524 2019 1514 1211 76 0
0001100fs2fs1rmfd1010011
755357

RV32I, RV64I

fence pred, succ

Fence memory and I/O. Ensure that no operation following the fence (that is specified in succ) can be observed before any operation preceding the fence (that is specified in pred), by any other RISC-V hart or external device.

Example: "fence r, w" means that all reads before the fence must be observed before all writes after the fence by all harts and devices.

Address space is divided into two types: main memory and input/output. Load and store operations to main memory are ordered by the R and W bits. Load and store operations to I/O addresses are ordered by the I and O bits.

pred and succ are 4 bit values specifying the types of operations where bit3=input, bit2=output, bit1=read, bit0=write. Any combination may be specified.

fm (fence mode): 0000 = normal fence, as described above; 1000 "TSO" (with pred=RW and succ=RW) = like normal fence but allow pred writes to be ordered after succ reads.

Fence(pred, succ)
31 2019 1514 1211 76 0
fm,pred,succ00000000000000001111
125357

fence

Fence on all memory and I/O. Pseudoinstruction.

fence iorw, iorw

RV32I, RV64I

fence.i

Fence instruction stream. Ensure that a subsequent instruction fetch on a RISC-V hart will see any previous data stores already visible to the same RISC-V hart. It does not ensure that other RISC-V harts will see the stores.

Fence(Store, Fetch)
31 2019 1514 1211 76 0
imm[11:0]00000001000000001111
125357

RV32D, RV64D

feq.d rd, fs1, fs2

Set if equal double-precision floating-point. Calculate fs1==fs2 and write 1 to rd if true, else 0.

If either input is NaN, the result is 0 and the invalid operation flag is only set if either result is a signaling NaN.

r[rd] = f[fs1] == f[fs2]
31 2524 2019 1514 1211 76 0
1010001fs2fs1010rd1010011
755357

RV32F, RV64F

feq.s rd, fs1, fs2

Set if equal single-precision floating-point. Calculate fs1==fs2 and write 1 to rd if true, else 0.

If either input is NaN, the result is 0 and the invalid operation flag is only set if either result is a signaling NaN.

r[rd] = f[fs1] == f[fs2]
31 2524 2019 1514 1211 76 0
1010000fs2fs1010rd1010011
755357

RV32D, RV64D

fld fd, imm(rs1)

Load double-precision floating-point. Copy doubleword from memory at address imm+rs1 into register fd.

f[fd] = M[x[rs1] + sext(imm)]
31 2019 1514 1211 76 0
imm[11:0]rs1011fd0000111
125357

Related: fsd


fld fd, imm(rs)

Floating-point load doubleword. Pseudoinstruction.

auipc rs, imm[31:12]
fld fd, imm[11:0](rs)

RV32D, RV64D

fle.d rd, fs1, fs2

Set if <= double-precision floating-point. Calculate fs1<=fs2 and write 1 to rd if true, else 0.

If either input is NaN, the result is 0 and the invalid operation flag is set.

r[rd] = f[fs1] <= f[fs2]
31 2524 2019 1514 1211 76 0
1010001fs2fs1000rd1010011
755357

RV32F, RV64F

fle.s rd, fs1, fs2

Set if <= single-precision floating-point. Calculate fs1<=fs2 and write 1 to rd if true, else 0.

If either input is NaN, the result is 0 and the invalid operation flag is set.

r[rd] = f[fs1] <= f[fs2]
31 2524 2019 1514 1211 76 0
1010000fs2fs1000rd1010011
755357

RV32D, RV64D

flt.d rd, fs1, fs2

Set if < double-precision floating-point. Calculate fs1<fs2 and write 1 to rd if true, else 0.

If either input is NaN, the result is 0 and the invalid operation flag is set.

r[rd] = f[fs1] < f[fs2]
31 2524 2019 1514 1211 76 0
1010001fs2fs1001rd1010011
755357

RV32F, RV64F

flt.s rd, fs1, fs2

Set if < single-precision floating-point. Calculate fs1<fs2 and write 1 to rd if true, else 0.

If either input is NaN, the result is 0 and the invalid operation flag is set.

r[rd] = f[fs1] < f[fs2]
31 2524 2019 1514 1211 76 0
1010000fs2fs1001rd1010011
755357

RV32F, RV64F

flw fd, imm(rs1)

Load single-precision floating-point. Copy word from memory at address imm+rs1 into register fd.

f[fd] = 1ext(M[x[rs1] + sext(imm)][31:0])
31 2019 1514 1211 76 0
imm[11:0]rs1010fd0000111
125357

Related: fsw


flw fd, imm(rs1)

Load single-precision floating-point. Pseudoinstruction.

auipc rs1, imm[31:12]
flw fd, imm[11:0](rs1)

RV32D, RV64D

fmadd.d fd, fs1, fs2, fs3

Multiply and add double-precision floating-point. Calculate fs1*fs2+fs3 and put the result in fd.

f[fd] = (f[fs1] * f[fs2]) + f[fs3]
31 2726 2524 2019 1514 1211 76 0
fs301fs2fs1000fd1000011
5255357

RV32F, RV64F

fmadd.s fd, fs1, fs2, fs3

Multiply and add single-precision floating-point. Calculate fs1*fs2+fs3 and put the result in fd.

f[fd] = (f[fs1] * f[fs2]) + f[fs3]
31 2726 2524 2019 1514 1211 76 0
fs300fs2fs1000fd1000011
5255357

RV32D, RV64D

fmax.d fd, fs1, fs2

Maximum double-precision floating-point. Calculate the maximum value of fs1 and fs2 and put the result in fd.

f[fd] = max(f[fs1], f[fs2])
31 2524 2019 1514 1211 76 0
0010101fs2fs1001fd1010011
755357

RV32F, RV64F

fmax.s fd, fs1, fs2

Maximum single-precision floating-point. Calculate the maximum value of fs1 and fs2 and put the result in fd.

f[fd] = max(f[fs1], f[fs2])
31 2524 2019 1514 1211 76 0
0010100fs2fs1001fd1010011
755357

RV32D, RV64D

fmin.d fd, fs1, fs2

Minimum double-precision floating-point. Calculate the minimum value of fs1 and fs2 and put the result in fd.

f[fd] = min(f[fs1], f[fs2])
31 2524 2019 1514 1211 76 0
0010101fs2fs1000fd1010011
755357

RV32F, RV64F

fmin.s fd, fs1, fs2

Minimum single-precision floating-point. Calculate the minimum value of fs1 and fs2 and put the result in fd.

f[fd] = min(f[fs1], f[fs2])
31 2524 2019 1514 1211 76 0
0010100fs2fs1000fd1010011
755357

RV32D, RV64D

fmsub.d fd, fs1, fs2, fs3

Multiply and subtract double-precision floating-point. Calculate fs1*fs2-fs3 and put the result in fd.

f[fd] = (f[fs1] * f[fs2]) - f[fs3]
31 2726 2524 2019 1514 1211 76 0
fs301fs2fs1000fd1000111
5255357

RV32F, RV64F

fmsub.s fd, fs1, fs2, fs3

Multiply and subtract single-precision floating-point. Calculate fs1*fs2-fs3 and put the result in fd.

f[fd] = (f[fs1] * f[fs2]) - f[fs3]
31 2726 2524 2019 1514 1211 76 0
fs300fs2fs1000fd1000111
5255357

RV32D, RV64D

fmul.d fd, fs1, fs2

Multiply double-precision floating-point. Calculate fs1*fs2 and put the result in fd.

The rm field is rounding mode.

f[fd] = f[fs1] * f[fs2]
31 2524 2019 1514 1211 76 0
0001001fs2fs1rmfd1010011
755357

RV32F, RV64F

fmul.s fd, fs1, fs2

Multiply single-precision floating-point. Calculate fs1*fs2 and put the result in fd.

The rm field is rounding mode.

f[fd] = f[fs1] * f[fs2]
31 2524 2019 1514 1211 76 0
0001000fs2fs1rmfd1010011
755357

fmv.d fd, fs

Copy double-precision register. Pseudoinstruction.

fsgnj.d fd, fs, fs

RV64D

fmv.d.x fd, rs

Move 64-bit integer to single-precision floating-point. The bits are not modified.

f[fd] = r[rs]
31 2524 2019 1514 1211 76 0
111100100000rs000fd1010011
755357

fmv.s fd, fs

Copy single-precision register. Pseudoinstruction.

fsgnj.s fd, fs, fs

RV32F, RV64F

fmv.w.x fd, rs

Move 32-bit integer to single-precision floating-point. The bits are not modified.

f[fd] = 1ext(r[rs][31:0])
31 2524 2019 1514 1211 76 0
111100000000rs000fd1010011
755357

RV64D

fmv.x.d rd, fs

Move double-precision floating-point to 64-bit integer. The bits are not modified.

x[rd] = sext(f[fs])
31 2524 2019 1514 1211 76 0
111000100000fs000rd1010011
755357

RV32F, RV64F

fmv.x.w rd, fs

Move single-precision floating-point to 32-bit integer. The bits are not modified.

x[rd] = sext(f[fs][31:0])
31 2524 2019 1514 1211 76 0
111000000000fs000rd1010011
755357

fneg.d fd, fs

Double-precision negate. Pseudoinstruction.

fsgnjn.d fd, fs, fs

fneg.s fd, fs

Single-precision negate. Pseudoinstruction.

fsgnjn.s fd, fs, fs

RV32D, RV64D

fnmadd.d fd, fs1, fs2, fs3

Negative multiply and add double-precision floating-point. Calculate -(fs1*fs2)-fs3 and put the result in fd.

f[fd] = -(f[fs1] * f[fs2]) - f[fs3]
31 2726 2524 2019 1514 1211 76 0
fs301fs2fs1000fd1001111
5255357

RV32F, RV64F

fnmadd.s fd, fs1, fs2, fs3

Negative multiply and add single-precision floating-point. Calculate -(fs1*fs2)-fs3 and put the result in fd.

f[fd] = -(f[fs1] * f[fs2]) - f[fs3]
31 2726 2524 2019 1514 1211 76 0
fs300fs2fs1000fd1001111
5255357

RV32D, RV64D

fnmsub.d fd, fs1, fs2, fs3

Negative multiply and subtract double-precision floating-point. Calculate -(fs1*fs2)+fs3 and put the result in fd.

f[fd] = -(f[fs1] * f[fs2]) + f[fs3]
31 2726 2524 2019 1514 1211 76 0
fs301fs2fs1000fd1001011
5255357

RV32F, RV64F

fnmsub.s fd, fs1, fs2, fs3

Negative multiply and subtract single-precision floating-point. Calculate -(fs1*fs2)+fs3 and put the result in fd.

f[fd] = -(f[fs1] * f[fs2]) + f[fs3]
31 2726 2524 2019 1514 1211 76 0
fs300fs2fs1000fd1001011
5255357

RV32D, RV64D

fsd fs2, imm(rs1)

Store double-precision floating-point. Copy register fs2 as doubleword into memory at address imm+rs1.

M[x[rs1] + sext(imm)] = f[fs2]
31 2524 2019 1514 1211 76 0
imm[11:5]fs2rs1011imm[4:0]0100111
755357

Related: fld


fsd fs2, imm(rs1)

Floating-point store doubleword. Pseudoinstruction.

auipc rs1, imm[31:12]
fsd fs2, imm[11:0](rs1)

RV32D, RV64D

fsgnj.d fd, fs1, fs2

Sign inject for double-precision floating-point.

Move fs1, with the sign bit of fs2, into fd.

f[fd] = f[fs1][62:0] | (f[fs2][63] << 63)
31 2524 2019 1514 1211 76 0
0010001fs2fs1000fd1001011
755357

RV32D, RV64D

fsgnjn.d fd, fs1, fs2

Negative sign inject for double-precision floating-point.

Move fs1, with the sign bit of ~fs2, into fd.

f[fd] = f[fs1][62:0] | (~(f[fs2][63]) << 63)
31 2524 2019 1514 1211 76 0
0010001fs2fs1001fd1001011
755357

RV32F, RV64F

fsgnjn.s fd, fs1, fs2

Negative sign inject for single-precision floating-point.

Move fs1, with the sign bit of ~fs2, into fd.

f[fd] = f[fs1][30:0] | (~(f[fs2][31]) << 31)
31 2524 2019 1514 1211 76 0
0010000fs2fs1001fd1001011
755357

RV32F, RV64F

fsgnj.s fd, fs1, fs2

Sign inject for single-precision floating-point.

Move fs1, with the sign bit of fs2, into fd.

f[fd] = f[fs1][30:0] | (f[fs2][31] << 31)
31 2524 2019 1514 1211 76 0
0010000fs2fs1000fd1001011
755357

RV32D, RV64D

fsgnjx.d fd, fs1, fs2

Xor sign inject for double-precision floating-point.

Move fs1, with the sign bit of fs1^fs2, into fd.

f[fd] = f[fs1][62:0] | ((f[fs1][63] ^ f[fs2][63]) << 63)
31 2524 2019 1514 1211 76 0
0010001fs2fs1010fd1001011
755357

RV32F, RV64F

fsgnjx.s fd, fs1, fs2

Xor sign inject for single-precision floating-point.

Move fs1, with the sign bit of fs1^fs2, into fd.

f[fd] = f[fs1][30:0] | ((f[fs1][31] ^ f[fs2][31]) << 31)
31 2524 2019 1514 1211 76 0
0010000fs2fs1010fd1001011
755357

RV32D, RV64D

fsqrt.d fd, fs1

Square root double-precision floating-point. Calculate sqrt(fs1) and put the result in fd.

The rm field is rounding mode.

f[fd] = sqrt(f[fs1])
31 2524 2019 1514 1211 76 0
010110100000fs1rmfd1010011
755357

RV32F, RV64F

fsqrt.s fd, fs1

Square root single-precision floating-point. Calculate sqrt(fs1) and put the result in fd.

The rm field is rounding mode.

f[fd] = sqrt(f[fs1])
31 2524 2019 1514 1211 76 0
010110000000fs1rmfd1010011
755357

RV32D, RV64D

fsub.d fd, fs1, fs2

Subtract double-precision floating-point. Calculate fs1-fs2 and put the result in fd.

The rm field is rounding mode.

f[fd] = f[fs1] - f[fs2]
31 2524 2019 1514 1211 76 0
0000101fs2fs1rmfd1010011
755357

RV32F, RV64F

fsub.s fd, fs1, fs2

Subtract single-precision floating-point. Calculate fs1-fs2 and put the result in fd.

The rm field is rounding mode.

f[fd] = f[fs1] - f[fs2]
31 2524 2019 1514 1211 76 0
0000100fs2fs1rmfd1010011
755357

RV32F, RV64F

fsw fs2, imm(rs1)

Store single-precision floating-point. Copy register fs2 as word into memory at address imm+rs1.

M[x[rs1] + sext(imm)] = f[fs2][31:0]
31 2524 2019 1514 1211 76 0
imm[11:5]fs2rs1010imm[4:0]0100111
755357

Related: flw


fsw fs2, imm(rs1)

Store single-precision floating-point. Pseudoinstruction.

auipc rs1, imm[31:12]
fsw fs2, imm[11:0](rs1)

j imm

Jump. Pseudoinstruction.

jal x0, imm

RV32I, RV64I

jal rd, imm

Jump and link. Add imm (multiple of 2 bytes) to pc. Put the address of the instruction following the jump (pc + 4 before adding) in rd.

x[rd] = pc + 4
pc += sext(imm)
31 1211 76 0
imm[20,10:1,11,19:12]rd1101111
2057

Related: jalr


jal imm

Jump and link. Pseudoinstruction.

jal x1, imm

RV32I, RV64I

jalr rd, imm(rs1)

Jump and link register. Add imm and rs1, clear the least-significant bit and put the result in pc. Put the address of the instruction following the jump (pc + 4 before changing pc) in rd.

t = pc + 4
pc = (x[rs1] + sext(imm)) & ∼1
x[rd] = t
31 2019 1514 1211 76 0
imm[11:0]rs1000rd1100111
125357

Related: jal, call, tail


jalr rs

Jump and link register. Pseudoinstruction.

jalr x1, 0(rs)

jr rs

Jump register. Pseudoinstruction.

jalr x0, 0(rs)

la rd, imm

Load address. Pseudoinstruction.

auipc rd, imm[31:12]
addi rd, rd, imm[11:0]

RV32I, RV64I

lb rd, imm(rs1)

Load byte. Copy one byte from memory at address imm+rs1 into register rd.

x[rd] = sext(M[x[rs1] + sext(imm)][7:0])
31 2019 1514 1211 76 0
imm[11:0]rs1000rd0000011
125357

Related: lbu, sb


lb rd, imm

Load byte. Pseudoinstruction.

auipc rd, imm[31:12]
lb rd, imm[11:0](rd)

RV32I, RV64I

lbu rd, imm(rs1)

Load byte, unsigned. Copy one byte from memory at address imm+rs1 into register rd.

x[rd] = M[x[rs1] + sext(imm)][7:0]
31 2019 1514 1211 76 0
imm[11:0]rs1100rd0000011
125357

Related: lb, sb


RV64I

ld rd, imm(rs1)

Load doubleword. Copy doubleword from memory at address imm+rs1 into register rd.

x[rd] = sext(M[x[rs1] + sext(imm)][63:0])
31 2019 1514 1211 76 0
imm[11:0]rs1011rd0000011
125357

Related: sd, lr.d


ld rd, imm

Load doubleword. Pseudoinstruction.

auipc rd, imm[31:12]
ld rd, imm[11:0](rd)

RV32I, RV64I

lh rd, imm(rs1)

Load halfword. Copy halfword from memory at address imm+rs1 into register rd.

x[rd] = sext(M[x[rs1] + sext(imm)][15:0])
31 2019 1514 1211 76 0
imm[11:0]rs1001rd0000011
125357

Related: lhu, sh


lh rd, imm

Load halfword. Pseudoinstruction.

auipc rd, imm[31:12]
lh rd, imm[11:0](rd)

RV32I, RV64I

lhu rd, imm(rs1)

Load halfword, unsigned. Copy halfword from memory at address imm+rs1 into register rd.

x[rd] = M[x[rs1] + sext(imm)][15:0]
31 2019 1514 1211 76 0
imm[11:0]rs1101rd0000011
125357

Related: lh, sh


li rd, imm

Load immediate. Pseudoinstruction.


RV64IA

lr.d rd, rs1

Load-reserve doubleword. Copy doubleword from memory at address rs1 and put it in rd.

In addition to loading memory, remember what bytes were loaded so that this instruction can be paired with sc.d.

x[rd] = sext(M[x[rs1]][63:0])
Reserve(x[rs1]:x[rs1]+63)
31 2524 2019 1514 1211 76 0
00010, aq, rl00000rs1011rd0100000
755357

Related: sc.d, ld


RV32IA, RV64IA

lr.w rd, rs1

Load-reserve word. Copy word from memory at address rs1 and put it in rd.

In addition to loading memory, remember what bytes were loaded so that this instruction can be paired with sc.w.

x[rd] = sext(M[x[rs1]][31:0])
Reserve(x[rs1]:x[rs1]+31)
31 2524 2019 1514 1211 76 0
00010, aq, rl00000rs1010rd0100000
755357

Related: sc.w, lw


RV32I, RV64I

lui rd, imm[31:12]

Load upper immediate. Can be used to build 32-bit constants. Put upper 20 bits of imm in rd and fill lower 12 bits with zeros.

x[rd] = sext(imm[31:12] << 12)
31 1211 76 0
imm[31:12]rd0110111
2057

Related: auipc


RV32I, RV64I

lw rd, imm(rs1)

Load word. Copy word from memory at address imm+rs1 into register rd.

x[rd] = sext(M[x[rs1] + sext(imm)][31:0])
31 2019 1514 1211 76 0
imm[11:0]rs1010rd0000011
125357

Related: sw


lw rd, imm

Load word. Pseudoinstruction.

auipc rd, imm[31:12]
lw rd, imm[11:0](rd)

RV64I

lwu rd, imm(rs1)

Load word, unsigned. Copy word from memory at address imm+rs1 into register rd.

x[rd] = M[x[rs1] + sext(imm)][31:0]
31 2019 1514 1211 76 0
imm[11:0]rs1110rd0000011
125357

Related: lw


RV32M, RV64M

mul rd, rs1, rs2

Multiply. Multiply rs1 and rs2 and put the lower bits of the result in rd. Arithmetic overflow is ignored.

x[rd] = (x[rs1] *s x[rs2])[XHI:0]
31 2524 2019 1514 1211 76 0
0000001rs2rs1000rd0110011
755357

RV32M, RV64M

mulh rd, rs1, rs2

Multiply upper. Multiply rs1 and rs2 and put the upper bits of the result in rd.

x[rd] = (x[rs1] *s x[rs2])[DXHI:XLEN]
31 2524 2019 1514 1211 76 0
0000001rs2rs1001rd0110011
755357

RV32M, RV64M

mulhsu rd, rs1, rs2

Multiply upper signed*unsigned. Multiply signed rs1 and unsigned rs2 and put the upper bits of the result in rd.

x[rd] = (x[rs1] *s,u x[rs2])[DXHI:XLEN]
31 2524 2019 1514 1211 76 0
0000001rs2rs1010rd0110011
755357

RV32M, RV64M

mulhu rd, rs1, rs2

Multiply upper unsigned. Multiply unsigned rs1 and unsigned rs2 and put the upper bits of the result in rd.

x[rd] = (x[rs1] *u x[rs2])[DXHI:XLEN]
31 2524 2019 1514 1211 76 0
0000001rs2rs1011rd0110011
755357

RV64M

mulw rd, rs1, rs2

Multiply word. Multiply the lower 32 bits of rs1 and rs2 and put the lower bits of the result in rd. Arithmetic overflow is ignored.

x[rd] = sext((x[rs1] *s x[rs2])[31:0])
31 2524 2019 1514 1211 76 0
0000001rs2rs1000rd0111011
755357

mv rd, rs

Copy register. Pseudoinstruction.

addi rd, rs, 0

neg rd, rs

Two's complement. Pseudoinstruction.

sub rd, x0, rs

negw rd, rs

Two's complement word. Pseudoinstruction.

subw rd, x0, rs

nop

No operation. Pseudoinstruction.

addi x0, x0, 0

not rd, rs

One's complement. Pseudoinstruction.

xori rd, rs, -1

RV32I, RV64I

or rd, rs1, rs2

OR. Calculate bitwise OR on rs1 and rs2 and put the result in rd.

x[rd] = x[rs1] | x[rs2]
31 2524 2019 1514 1211 76 0
0000000rs2rs1110rd0110011
755357

RV32I, RV64I

ori rd, rs1, imm

OR immediate. Calculate bitwise OR on rs1 and imm and put the result in rd.

x[rd] = x[rs1] | sext(imm)
31 2019 1514 1211 76 0
imm[11:0]rs1110rd0010011
125357

RV32M, RV64M

rem rd, rs1, rs2

Remainder. Divide rs1 by rs2 and put the remainder of the result (rounded towards zero) in rd.

x[rd] = x[rs1] /s x[rs2]
31 2524 2019 1514 1211 76 0
0000001rs2rs1110rd0110011
755357

Related: div


RV32M, RV64M

remu rd, rs1, rs2

Remainder unsigned. Divide unsigned rs1 by unsigned rs2 and put the remainder of the result (rounded towards zero) in rd.

x[rd] = x[rs1] /u x[rs2]
31 2524 2019 1514 1211 76 0
0000001rs2rs1111rd0110011
755357

Related: divu


RV64M

remuw rd, rs1, rs2

Remainder unsigned word. Divide the lower 32 bits of unsigned rs1 by the lower 32 bits of unsigned rs2 and put the remainder of the result (rounded towards zero) in rd.

x[rd] = x[rs1][31:0] /u x[rs2][31:0]
31 2524 2019 1514 1211 76 0
0000001rs2rs1111rd0111011
755357

Related: divuw


RV64M

remw rd, rs1, rs2

Remainder word. Divide the lower 32 bits of rs1 by the lower 32 bits of rs2 and put the remainder of the result (rounded towards zero) in rd.

x[rd] = x[rs1][31:0] /s x[rs2][31:0]
31 2524 2019 1514 1211 76 0
0000001rs2rs1110rd0111011
755357

Related: divw


ret

Return from subroutine. Pseudoinstruction.

jalr x0, 0(x1)

RV32I, RV64I

sb rs2, imm(rs1)

Store byte. Copy register rs2 as byte into memory at address imm+rs1.

M[x[rs1] + sext(imm)] = x[rs2][7:0]
31 2524 2019 1514 1211 76 0
imm[11:5]rs2rs1000imm[4:0]0100011
755357

Related: lb


sb rd, imm, rs1

Store byte. Pseudoinstruction.

auipc rs1, imm[31:12]
sb rd, imm[11:0](rs1)

RV64IA

sc.d rd, rs1, rs2

Store-conditional doubleword. Conditionally copy register rs2 as doubleword into memory at address rs1 and return error code in rd.

Result in rd: 0=success, non-0=failure. Success means that the value at the target address has not changed since the last load-reserve by the same hart and that the target range of memory is included in the reserved range by the last load-reserve.

if (ReservationIsValid(x[rs1]:x[rs1]+63)) {
  M[x[rs1]] = x[rs2][63:0]
  x[rd] = 0
} else {
  x[rd] = 1 // or other non-0
}
31 2524 2019 1514 1211 76 0
00011, aq, rlrs2rs1011rd0101111
755357

Related: lr.d, sd


RV32IA, RV64IA

sc.w rd, rs1, rs2

Store-conditional word. Conditionally copy register rs2 as word into memory at address rs1 and return error code in rd.

Result in rd: 0=success, non-0=failure. Success means that the value at the target address has not changed since the last load-reserve by the same hart and that the target range of memory is included in the reserved range by the last load-reserve.

if (ReservationIsValid(x[rs1]:x[rs1]+31)) {
  M[x[rs1]] = x[rs2][31:0]
  x[rd] = 0
} else {
  x[rd] = 1 // or other non-0
}
31 2524 2019 1514 1211 76 0
00011, aq, rlrs2rs1010rd0101111
755357

Related: lr.w, sw


RV64I

sd rs2, imm(rs1)

Store doubleword. Copy register rs2 as doubleword into memory at address imm+rs1.

M[x[rs1] + sext(imm)] = x[rs2][63:0]
31 2524 2019 1514 1211 76 0
imm[11:5]rs2rs1011imm[4:0]0100011
755357

Related: ld, sc.d


sd rd, imm, rs1

Store doubleword. Pseudoinstruction.

auipc rs1, imm[31:12]
sd rd, imm[11:0](rs1)

sext.w rd, rs

Sign extend word. Pseudoinstruction.

addiw rd, rs, 0

seqz rd, rs

Set if = zero. Pseudoinstruction.

sltiu rd, rs, 1

sgtz rd, rs

Set if > zero. Pseudoinstruction.

slt rd, x0, rs

RV32I, RV64I

sh rs2, imm(rs1)

Store halfword. Copy register rs2 as halfword into memory at address imm+rs1.

M[x[rs1] + sext(imm)] = x[rs2][15:0]
31 2524 2019 1514 1211 76 0
imm[11:5]rs2rs1001imm[4:0]0100011
755357

Related: lh


sh rd, imm(rs)

Store halfword. Pseudoinstruction.

auipc rs, imm[31:12]
sh rd, imm[11:0](rs)

RV32I, RV64I

sll rd, rs1, rs2

Shift left logical. Shift rs1 left rs2 bits and put the result in rd. The lower bits are filled with zeros. Only the lower 5 bits (RV32I) or 6 bits (RV64I) in rs2 are used.

x[rd] = x[rs1] << x[rs2]
31 2524 2019 1514 1211 76 0
0000000rs2rs1001rd0110011
755357

Related: srl


RV32I

slli rd, rs1, imm

Shift left logical immediate. Shift rs1 left imm bits. The lower bits are filled with zeros.

x[rd] = x[rs1] << imm
31 2019 1514 1211 76 0
0000000, imm[4:0]rs1001rd0010011
125357

Related: srli


RV64I

slli rd, rs1, imm

Shift left logical immediate. Shift rs1 left imm bits. The lower bits are filled with zeros.

x[rd] = x[rs1] << imm
31 2019 1514 1211 76 0
000000, imm[5:0]rs1001rd0010011
125357

Related: srli


RV64I

slliw rd, rs1, imm

Shift left logical word immediate. Shift rs1 left imm bits. The lower bits are filled with zeros. imm[5] must be 0.

x[rd] = sext((x[rs1] << imm)[31:0])
31 2019 1514 1211 76 0
000000, imm[5:0]rs1001rd0011011
125357

Related: srliw


RV64I

sllw rd, rs1, rs2

Shift left logical word. Shift rs1 left rs2 bits and put the result in rd. The lower bits are filled with zeros. Only the lower 5 bits of rs2 are used.

x[rd] = sext((x[rs1] << x[rs2][4:0])[31:0])
31 2524 2019 1514 1211 76 0
0000000rs2rs1001rd0111011
755357

Related: srlw


RV32I, RV64I

slt rd, rs1, rs2

Set if <. Put 1 in rd if rs1 is less than (signed) rs2, else 0 is written to rd.

x[rd] = x[rs1] <s x[rs2]
31 2524 2019 1514 1211 76 0
0000000rs2rs1010rd0110011
755357

RV32I, RV64I

slti rd, rs1, imm

Set if < immediate. Put 1 in rd if rs1 is less than (signed) imm, else 0 is written to rd.

x[rd] = x[rs1] <s sext(imm)
31 2019 1514 1211 76 0
imm[11:0]rs1010rd0010011
125357

RV32I, RV64I

sltiu rd, rs1, imm

Set if < immediate, unsigned. Put 1 in rd if rs1 is less than (unsigned) imm, else 0 is written to rd.

x[rd] = x[rs1] <u sext(imm)
31 2019 1514 1211 76 0
imm[11:0]rs1011rd0010011
125357

RV32I, RV64I

sltu rd, rs1, rs2

Set if <, unsigned. Put 1 in rd if rs1 is less than (unsigned) rs2, else 0 is written to rd.

x[rd] = x[rs1] <u x[rs2]
31 2524 2019 1514 1211 76 0
0000000rs2rs1011rd0110011
755357

sltz rd, rs

Set if < zero. Pseudoinstruction.

slt rd, rs, x0

snez rd, rs

Set if ≠ zero. Pseudoinstruction.

sltu rd, x0, rs

RV32I, RV64I

sra rd, rs1, rs2

Shift right arithmetic. Shift rs1 right rs2 bits and put the result in rd. The upper bits are filled with the original sign bit. Only the lower 5 bits (RV32I) or 6 bits (RV64I) in rs2 are used.

x[rd] = x[rs1] >>s x[rs2]
31 2524 2019 1514 1211 76 0
0100000rs2rs1101rd0110011
755357

Related: srl


RV32I

srai rd, rs1, imm

Shift right arithmetic immediate. Shift rs1 right imm bits. The upper bits are filled with the original sign bit.

x[rd] = x[rs1] >>s imm
31 2019 1514 1211 76 0
0100000, imm[4:0]rs1101rd0010011
125357

Related: srli


RV64I

srai rd, rs1, imm

Shift right arithmetic immediate. Shift rs1 right imm bits. The upper bits are filled with the original sign bit.

x[rd] = x[rs1] >>s imm
31 2019 1514 1211 76 0
010000, imm[5:0]rs1101rd0010011
125357

Related: srli


RV64I

sraiw rd, rs1, imm

Shift right arithmetic word immediate. Shift rs1 right imm bits. The upper bits are filled with the original sign bit.

x[rd] = sext(x[rs1][31:0] >>s imm)
31 2019 1514 1211 76 0
010000, imm[5:0]rs1101rd0011011
125357

Related: srliw


RV64I

sraw rd, rs1, rs2

Shift right arithmetic word. Shift rs1 right rs2 bits and put the result in rd. The upper bits are filled with the original sign bit. Only the lower 5 bits in rs2 are used.

x[rd] = sext(x[rs1][31:0] >>s x[rs2][4:0])
31 2524 2019 1514 1211 76 0
0100000rs2rs1101rd0111011
755357

Related: srlw


RV32I, RV64I

srl rd, rs1, rs2

Shift right logical. Shift rs1 right rs2 bits and put the result in rd. The upper bits are filled with zeros. Only the lower 5 bits (RV32I) or 6 bits (RV64I) in rs2 are used.

x[rd] = x[rs1] >>u x[rs2]
31 2524 2019 1514 1211 76 0
0000000rs2rs1101rd0110011
755357

Related: sll, sra


RV32I

srli rd, rs1, imm

Shift right logical immediate. Shift rs1 right imm bits. The upper bits are filled with zeros.

x[rd] = x[rs1] >>u imm
31 2019 1514 1211 76 0
0000000, imm[4:0]rs1101rd0010011
125357

Related: slli, srai


RV64I

srli rd, rs1, imm

Shift right logical immediate. Shift rs1 right imm bits. The upper bits are filled with zeros.

x[rd] = x[rs1] >>u imm
31 2019 1514 1211 76 0
000000, imm[5:0]rs1101rd0010011
125357

Related: slli, srai


RV64I

srliw rd, rs1, imm

Shift right logical word immediate. Shift rs1 right imm bits. The upper bits are filled with zeros. imm[5] must be 0.

x[rd] = sext(x[rs1][31:0] >>u imm)
31 2019 1514 1211 76 0
000000, imm[5:0]rs1101rd0011011
125357

Related: slliw, sraiw


RV64I

srlw rd, rs1, rs2

Shift right logical word. Shift rs1 right rs2 bits and put the result in rd. The upper bits are filled with zeros. Only the lower 5 bits in rs2 are used.

x[rd] = sext(x[rs1][31:0] >>u x[rs2][4:0])
31 2524 2019 1514 1211 76 0
0000000rs2rs1101rd0111011
755357

Related: sllw, sraw


RV32I, RV64I

sub rd, rs1, rs2

Subtract. Subtract rs2 from rs1 and put the result in rd. Arithmetic overflow is ignored.

x[rd] = x[rs1] - x[rs2]
31 2524 2019 1514 1211 76 0
0100000rs2rs1000rd0110011
755357

RV64I

subw rd, rs1, rs2

Subtract word. Subtract rs2 from rs1 and put the result in rd. Arithmetic overflow is ignored.

x[rd] = sext((x[rs1] - x[rs2])[31:0])
31 2524 2019 1514 1211 76 0
0100000rs2rs1000rd0111011
755357

RV32I, RV64I

sw rs2, imm(rs1)

Store word. Copy register rs2 as word into memory at address imm+rs1.

M[x[rs1] + sext(imm)] = x[rs2][31:0]
31 2524 2019 1514 1211 76 0
imm[11:5]rs2rs1010imm[4:0]0100011
755357

Related: lw


sw rd, imm(rs)

Store word. Pseudoinstruction.

auipc rs, imm[31:12]
sw rd, imm[11:0](rs)

tail imm

Tail call far-away subroutine. Pseudoinstruction.

auipc x6, imm[31:12]
jalr x0, imm[11:0](x6)

Related: call


RV32I, RV64I

xor rd, rs1, rs2

Exclusive OR. Calculate bitwise XOR on rs1 and rs2 and put the result in rd.

x[rd] = x[rs1] ^ x[rs2]
31 2524 2019 1514 1211 76 0
0000000rs2rs1100rd0110011
755357

RV32I, RV64I

xori rd, rs1, imm

Exclusive OR immediate. Calculate bitwise XOR on rs1 and imm and put the result in rd.

x[rd] = x[rs1] ^ sext(imm)
31 2019 1514 1211 76 0
imm[11:0]rs1100rd0010011
125357