RISC-V instructions

Contents:

Instructions by category

Int Arith: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 mul mulh mulhsu mulhu mulw rem remu remuw remw sub subw
Float Arith: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 fnmadd.d fnmadd.s fnmsub.d fnmsub.s fsqrt.d fsqrt.s fsub.d fsub.s
Logic:amoand.d amoand.w amoor.d amoor.w amoxor.d amoxor.w and andi or ori xor xori
Shift:sll slli slliw sllw sra srai sraiw sraw srl srli srliw srlw
Branch:beq bge bgeu blt bltu bne
Jump:jal jalr
Memory:amoswap.d amoswap.w 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 slt slti sltiu sltu
Control/Status:csrrc csrrci csrrs csrrsi csrrw csrrwi
Uncategorized:auipc ebreak ecall fclass.d fclass.s fmv.d.x fmv.w.x fmv.x.d fmv.x.w fsgnj.d fsgnjn.d fsgnjn.s fsgnj.s fsgnjx.d fsgnjx.s lui

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/.

Assembler Instructions

These are the instructions that your assembler parses and compiles to machine code.

add rd, rs1, rs2 Add
addi rd, rs1, imm Add immediate
addiw rd, rs1, imm Add word immediate
addw rd, rs1, rs2 Add word
amoadd.d rd, rs2, (rs1) Atomic add doubleword
amoadd.w rd, rs2, (rs1) Atomic add word
amoand.d rd, rs2, (rs1) Atomic AND doubleword
amoand.w rd, rs2, (rs1) Atomic AND word
amomax.d rd, rs2, (rs1) Atomic maximum doubleword
amomaxu.d rd, rs2, (rs1) Atomic unsigned maximum word
amomaxu.w rd, rs2, (rs1) Atomic unsigned maximum word
amomax.w rd, rs2, (rs1) Atomic maximum word
amomin.d rd, rs2, (rs1) Atomic minimum doubleword
amominu.d rd, rs2, (rs1) Atomic unsigned minimum word
amominu.w rd, rs2, (rs1) Atomic unsigned minimum word
amomin.w rd, rs2, (rs1) Atomic minimum word
amoor.d rd, rs2, (rs1) Atomic OR doubleword
amoor.w rd, rs2, (rs1) Atomic OR word
amoswap.d rd, rs2, (rs1) Atomic swap doubleword
amoswap.w rd, rs2, (rs1) Atomic swap word
amoxor.d rd, rs2, (rs1) Atomic XOR doubleword
amoxor.w rd, rs2, (rs1) Atomic XOR word
and rd, rs1, rs2 AND
andi rd, rs1, imm AND immediate
auipc rd, imm[31:12] Add upper immediate to pc
beq rs1, rs2, imm Branch if =
beqz rs1, imm Branch if = zero
bge rs1, rs2, imm Branch if ≥
bgeu rs1, rs2, imm Branch if ≥, unsigned
bgez rs1, imm Branch if ≥ zero
bgt rs1, rs2, imm Branch if >
bgtu rs1, rs2, imm Branch if >, unsigned
bgtz rs1, imm Branch if > zero
ble rs1, rs2, imm Branch if ≤
bleu rs1, rs2, imm Branch if ≤, unsigned
blez rs, imm Branch if ≤ zero
blt rs1, rs2, imm Branch if <
bltu rs1, rs2, imm Branch if <, unsigned
bltz rs, imm Branch if < zero
bne rs1, rs2, imm Branch if ≠
bnez rs, imm Branch if ≠ zero
call imm Call far-away subroutine
csrrc rd csr rs1 Control and status register read and clear
csrrci rd csr imm[4:0] Control and status register read and clear immediate
csrrs rd, csr, rs1 Control and status register read and set
csrrsi rd, csr, imm[4:0] Control and status register read and set immediate
csrrw rd, csr, rs1 Control and status register read and write
csrrwi rd, csr, imm[4:0] Control and status register read and write immediate
div rd, rs1, rs2 Divide
divu rd, rs1, rs2 Divide unsigned
divuw rd, rs1, rs2 Divide unsigned word
divw rd, rs1, rs2 Divide word
ebreak Environment breakpoint
ecall Environment call
fabs.d fd, fs Double-precision absolute value
fabs.s fd, fs Single-precision absolute value
fadd.d fd, fs1, fs2 Add double-precision floating-point
fadd.s fd, fs1, fs2 Add single-precision floating-point
fclass.d rd, fs Classify double-precision floating-point
fclass.s rd, fs Classify single-precision floating-point
fcvt.d.l fd, rs1 Convert 64-bit integer to double-precision floating-point
fcvt.d.lu fd, rs1 Convert 64-bit unsigned integer to double-precision floating-point
fcvt.d.s fd, fs1 Convert single-precision to double-precision floating-point
fcvt.d.w fd, rs1 Convert 32-bit integer to double-precision floating-point
fcvt.d.wu fd, rs1 Convert 32-bit unsigned integer to double-precision floating-point
fcvt.l.d rd, fs1 Convert double-precision floating-point to 64-bit integer
fcvt.l.s rd, fs1 Convert single-precision floating-point to 64-bit integer
fcvt.lu.d rd, fs1 Convert double-precision floating-point to unsigned 64-bit integer
fcvt.lu.s rd, fs1 Convert single-precision floating-point to unsigned 64-bit integer
fcvt.s.d fd, fs1 Convert double-precision to single-precision floating-point
fcvt.s.l fd, rs1 Convert 64-bit integer to single-precision floating-point
fcvt.s.lu fd, rs1 Convert 64-bit unsigned integer to single-precision floating-point
fcvt.s.w fd, rs1 Convert 32-bit integer to single-precision floating-point
fcvt.s.wu fd, rs1 Convert 32-bit unsigned integer to single-precision floating-point
fcvt.w.d rd, fs1 Convert double-precision floating-point to 32-bit integer
fcvt.w.s rd, fs1 Convert single-precision floating-point to 32-bit integer
fcvt.wu.d rd, fs1 Convert double-precision floating-point to unsigned 32-bit integer
fcvt.wu.s rd, fs1 Convert single-precision floating-point to unsigned 32-bit integer
fdiv.d fd, fs1, fs2 Divide double-precision floating-point
fdiv.s fd, fs1, fs2 Divide single-precision floating-point
fence pred, succ Fence memory and I/O
fence.i Fence instruction stream
feq.d rd, fs1, fs2 Set if equal double-precision floating-point
feq.s rd, fs1, fs2 Set if equal single-precision floating-point
fld fd, imm(rs1) Load double-precision floating-point
fle.d rd, fs1, fs2 Set if <= double-precision floating-point
fle.s rd, fs1, fs2 Set if <= single-precision floating-point
flt.d rd, fs1, fs2 Set if < double-precision floating-point
flt.s rd, fs1, fs2 Set if < single-precision floating-point
flw fd, imm(rs1) Load single-precision floating-point
fmadd.d fd, fs1, fs2, fs3 Multiply and add double-precision floating-point
fmadd.s fd, fs1, fs2, fs3 Multiply and add single-precision floating-point
fmax.d fd, fs1, fs2 Maximum double-precision floating-point
fmax.s fd, fs1, fs2 Maximum single-precision floating-point
fmin.d fd, fs1, fs2 Minimum double-precision floating-point
fmin.s fd, fs1, fs2 Minimum single-precision floating-point
fmsub.d fd, fs1, fs2, fs3 Multiply and subtract double-precision floating-point
fmsub.s fd, fs1, fs2, fs3 Multiply and subtract single-precision floating-point
fmul.d fd, fs1, fs2 Multiply double-precision floating-point
fmul.s fd, fs1, fs2 Multiply single-precision floating-point
fmv.d fd, fs Copy double-precision register
fmv.d.x fd, rs Move 64-bit integer to single-precision floating-point
fmv.s fd, fs Copy single-precision register
fmv.w.x fd, rs Move 32-bit integer to single-precision floating-point
fmv.x.d rd, fs Move double-precision floating-point to 64-bit integer
fmv.x.w rd, fs Move single-precision floating-point to 32-bit integer
fneg.d fd, fs Double-precision negate
fneg.s fd, fs Single-precision negate
fnmadd.d fd, fs1, fs2, fs3 Negative multiply and add double-precision floating-point
fnmadd.s fd, fs1, fs2, fs3 Negative multiply and add single-precision floating-point
fnmsub.d fd, fs1, fs2, fs3 Negative multiply and subtract double-precision floating-point
fnmsub.s fd, fs1, fs2, fs3 Negative multiply and subtract single-precision floating-point
fsd fs2, imm(rs1) Store double-precision floating-point
fsgnj.d fd, fs1, fs2 Sign inject for double-precision floating-point
fsgnjn.d fd, fs1, fs2 Negative sign inject for double-precision floating-point
fsgnjn.s fd, fs1, fs2 Negative sign inject for single-precision floating-point
fsgnj.s fd, fs1, fs2 Sign inject for single-precision floating-point
fsgnjx.d fd, fs1, fs2 Xor sign inject for double-precision floating-point
fsgnjx.s fd, fs1, fs2 Xor sign inject for single-precision floating-point
fsqrt.d fd, fs1 Square root double-precision floating-point
fsqrt.s fd, fs1 Square root single-precision floating-point
fsub.d fd, fs1, fs2 Subtract double-precision floating-point
fsub.s fd, fs1, fs2 Subtract single-precision floating-point
fsw fs2, imm(rs1) Store single-precision floating-point
j imm Jump
jal rd, imm Jump and link
jalr rd, imm(rs1) Jump and link register
jr rs Jump register
la rd, imm Load address
lb rd, imm(rs1) Load byte
lbu rd, imm(rs1) Load byte, unsigned
ld rd, imm(rs1) Load doubleword
lh rd, imm(rs1) Load halfword
lhu rd, imm(rs1) Load halfword, unsigned
li rd, imm Load immediate
lr.d rd, rs1 Load-reserve doubleword
lr.w rd, rs1 Load-reserve word
lui rd, imm[31:12] Load upper immediate
lw rd, imm(rs1) Load word
lwu rd, imm(rs1) Load word, unsigned
mul rd, rs1, rs2 Multiply
mulh rd, rs1, rs2 Multiply upper
mulhsu rd, rs1, rs2 Multiply upper signed*unsigned
mulhu rd, rs1, rs2 Multiply upper unsigned
mulw rd, rs1, rs2 Multiply word
mv rd, rs Copy register
neg rd, rs Two's complement
negw rd, rs Two's complement word
nop No operation
not rd, rs One's complement
or rd, rs1, rs2 OR
ori rd, rs1, imm OR immediate
rem rd, rs1, rs2 Remainder
remu rd, rs1, rs2 Remainder unsigned
remuw rd, rs1, rs2 Remainder unsigned word
remw rd, rs1, rs2 Remainder word
ret Return from subroutine
sb rs2, imm(rs1) Store byte
sc.d rd, rs1, rs2 Store-conditional doubleword
sc.w rd, rs1, rs2 Store-conditional word
sd rs2, imm(rs1) Store doubleword
sext.w rd, rs Sign extend word
seqz rd, rs Set if = zero
sgtz rd, rs Set if > zero
sh rs2, imm(rs1) Store halfword
sll rd, rs1, rs2 Shift left logical
slli rd, rs1, imm Shift left logical immediate
slli rd, rs1, imm Shift left logical immediate
slliw rd, rs1, imm Shift left logical word immediate
sllw rd, rs1, rs2 Shift left logical word
slt rd, rs1, rs2 Set if <
slti rd, rs1, imm Set if < immediate
sltiu rd, rs1, imm Set if < immediate, unsigned
sltu rd, rs1, rs2 Set if <, unsigned
sltz rd, rs Set if < zero
snez rd, rs Set if ≠ zero
sra rd, rs1, rs2 Shift right arithmetic
srai rd, rs1, imm Shift right arithmetic immediate
srai rd, rs1, imm Shift right arithmetic immediate
sraiw rd, rs1, imm Shift right arithmetic word immediate
sraw rd, rs1, rs2 Shift right arithmetic word
srl rd, rs1, rs2 Shift right logical
srli rd, rs1, imm Shift right logical immediate
srli rd, rs1, imm Shift right logical immediate
srliw rd, rs1, imm Shift right logical word immediate
srlw rd, rs1, rs2 Shift right logical word
sub rd, rs1, rs2 Subtract
subw rd, rs1, rs2 Subtract word
sw rs2, imm(rs1) Store word
tail imm Tail call far-away subroutine
xor rd, rs1, rs2 Exclusive OR
xori rd, rs1, imm Exclusive OR immediate

Hardware Instructions

These are the instructions that your processor decodes and executes.


RV32I, RV64I

add

rd[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
imm[11:0]

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[4:0]
rs1[4:0]
imm[11:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
imm[11:0]

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[4:0]
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[4:0]
rs2[4:0]
imm[12:1]

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

RV32I, RV64I

bge

rs1[4:0]
rs2[4:0]
imm[12:1]

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[4:0]
rs2[4:0]
imm[12:1]

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

RV32I, RV64I

blt

rs1[4:0]
rs2[4:0]
imm[12:1]

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[4:0]
rs2[4:0]
imm[12:1]

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

RV32I, RV64I

bne

rs1[4:0]
rs2[4:0]
imm[12:1]

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

RV32I, RV64I

csrrc

rd[4:0]
csr[11:0]
rs1[4:0]

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[4:0]
csr[11:0]
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[4:0]
csr[11:0]
rs1[4:0]

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[4:0]
csr[11:0]
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[4:0]
csr[11:0]
rs1[4:0]

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[4:0]
csr[11:0]
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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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

RV32D, RV64D

fadd.d

fd[4:0]
fs1[4:0]
fs2[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
fs2[4:0]
rm[2:0]

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[4:0]
fs[4:0]

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[4:0]
fs[4:0]

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[4:0]
rs1[4:0]
rm[2:0]

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[4:0]
rs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
rs1[4:0]
rm[2:0]

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[4:0]
rs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
rs1[4:0]
rm[2:0]

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[4:0]
rs1[4:0]
rm[2:0]

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[4:0]
rs1[4:0]
rm[2:0]

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[4:0]
rs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
fs2[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
fs2[4:0]
rm[2:0]

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[3:0]
succ[3:0]
fm[3:0]

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

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
00000000000000000001000000001111
125357

RV32D, RV64D

feq.d

rd[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
rs1[4:0]
imm[11:0]

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


RV32D, RV64D

fle.d

rd[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
rs1[4:0]
imm[11:0]

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


RV32D, RV64D

fmadd.d

fd[4:0]
fs1[4:0]
fs2[4:0]
fs3[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]
fs3[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]
fs3[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]
fs3[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
fs2[4:0]
rm[2:0]

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

RV64D

fmv.d.x

fd[4:0]
rs[4:0]

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

RV32F, RV64F

fmv.w.x

fd[4:0]
rs[4:0]

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[4:0]
fs[4:0]

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[4:0]
fs[4:0]

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

RV32D, RV64D

fnmadd.d

fd[4:0]
fs1[4:0]
fs2[4:0]
fs3[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]
fs3[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]
fs3[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]
fs3[4:0]

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
rs1[4:0]
imm[11:0]

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


RV32D, RV64D

fsgnj.d

fd[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
fs2[4:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
fs2[4:0]
rm[2:0]

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[4:0]
fs1[4:0]
fs2[4:0]
rm[2:0]

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
rs1[4:0]
imm[11:0]

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


RV32I, RV64I

jal

rd[4:0]
imm[20:1]

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


RV32I, RV64I

jalr

rd[4:0]
rs1[4:0]
imm[11:0]

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


RV32I, RV64I

lb

rd[4:0]
rs1[4:0]
imm[11:0]

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


RV32I, RV64I

lbu

rd[4:0]
rs1[4:0]
imm[11:0]

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[4:0]
rs1[4:0]
imm[11:0]

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


RV32I, RV64I

lh

rd[4:0]
rs1[4:0]
imm[11:0]

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


RV32I, RV64I

lhu

rd[4:0]
rs1[4:0]
imm[11:0]

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


RV64IA

lr.d

rd[4:0]
rs1[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
aq[0]
rl[0]

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[4:0]
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[4:0]
rs1[4:0]
imm[11:0]

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


RV64I

lwu

rd[4:0]
rs1[4:0]
imm[11:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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

RV32I, RV64I

or

rd[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
imm[11:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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


RV32I, RV64I

sb

rs2[4:0]
rs1[4:0]
imm[11:0]

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


RV64IA

sc.d

rd[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
rs2[4:0]
aq[0]
rl[0]

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[4:0]
rs1[4:0]
imm[11:0]

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


RV32I, RV64I

sh

rs2[4:0]
rs1[4:0]
imm[11:0]

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


RV32I, RV64I

sll

rd[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
imm[4:0]

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[4:0]
rs1[4:0]
imm[5:0]

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[4:0]
rs1[4:0]
imm[5:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
imm[11:0]

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[4:0]
rs1[4:0]
imm[11:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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

RV32I, RV64I

sra

rd[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
imm[4:0]

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[4:0]
rs1[4:0]
imm[5:0]

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[4:0]
rs1[4:0]
imm[5:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
imm[4:0]

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[4:0]
rs1[4:0]
imm[5:0]

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[4:0]
rs1[4:0]
imm[5:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
imm[11:0]

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


RV32I, RV64I

xor

rd[4:0]
rs1[4:0]
rs2[4:0]

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[4:0]
rs1[4:0]
imm[11:0]

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