RV32I: Computational Instructions

There are 21 computational instructions.

rd denotes a _d_estination _r_egister, rs1 and rs2 some _s_ource _r_egisters. imm stands for "immediate value".

Instruction"C"Meaning
add rd, rs1, rs2rd = rs1 + rs2
sub rd, rs1, rs2rd = rs1 - rs2
sll rd, rs1, rs2rd = rs1 << rs2shift left logical by register
srl rd, rs1, rs2TODOshift right logical by register
sra rd, rs1, rs2TODOshift right arithm. by register
and rd, rs1, rs2rd = rs1 & rs2bitwise AND
or rd, rs1, rs2rd = rs1 | rs2bitwise OR
xor rd, rs1, rs2rd = rs1 ^ rs2bitwise XOR
slt rd, rs1, rs2rd = ((int)rs1 < (int)rs2)compare, set 1/0
sltu rd, rs1, rs2rd = ((uint)rs1 < (uint)rs2)compare, set 1/0
addi rd, rs1, immrd = rs1 + (int32_t)imm
slli rd, rs1, immrd = rs1 << imm[4:0]
srli rd, rs1, imm???shift right logical by immediate
srai rd, rs1, imm???shift right arithm. by immediate
andi rd, rs1, immrd = rs1 & immbitwise AND with immediate
ori rd, rs1, immrd = rs1 | immbitwise OR with immediate
xori rd, rs1, immrd = rs1 ^ immbitwise XOR with immediate
slti rd, rs1, immrd = ((int)rs1 < (int)imm)sign-extend imm, compare, set 1/0
sltui rd, rs1, imm_rd = ((uint)rs1 < (uint)imm)sign-extend imm, compare as unsigned, set 1/0
lui rd, immrd = (imm << 12)load upper immediate, set lower 12 bits to 0
auipc rd, immrd = pc + (imm << 12)add upper immediate to pc

Signed integers are stored as 2's complements. All of instructions sign-extend operands if needed.

Definitions:

  • logical left shift by n: equivalent to multiplication by 2^n.
  • logical right shift by n: equivalent to unsigned division by 2^n, rounding towards 0
  • logical arithmetical shift by n: equivalent to unsigned division by 2^n, rounding down

Notes:

  • not rd, rs1 can be implemented as xori rd, rs1, -1
  • a pseudoinstruction seqz: sltiu rd, rs1, 1, computes if rs1 is 0.
  • a pseudoinstruction li rd, imm: lui rd, imm[31:12]; addi rd, rd, imm[11:0]
  • nop is usually defined as addi x0, x0, 0

TODO: what happens on integer overflow?

auipc is a position-independent code shortcut, e.g.:

auipc   x4, 0x1
lw      x4, 0x234(x4)

allows to read a word from memory at pc + 0x1234 into x4

TODO: pc at which point?

Encoding auipc and lui

lui and auipc are U-type. Least significant byte looks like 37/B7, 17/97.

imm[31:12]rdopcode
lui01 101 11
auipc00 101 11

Encoding register instructions

Instructions with rs2 are R-type:

funct7rs2rs1funct3rdopcode
add000000000001 100 11
sub010000000001 100 11
sll000000000101 100 11
slt000000001001 100 11
sltu000000001101 100 11
xor000000010001 100 11
srl000000010101 100 11
sra010000010101 100 11
or000000011001 100 11
and000000011101 100 11

Encoding instructions with immediates

Everything else is I-type.

imm[11:5]imm[4:0]rs1funct3rdopcode
addi00000 100 11
slti01000 100 11
sltiu01100 100 11
xori10000 100 11
ori11000 100 11
andi11100 100 11
slli0000000shamt00100 100 11
srli0000000shamt10100 100 11
srai0100000shamt10100 100 11

Least significant byte

  • 13/93 for instructions with immediates
  • 33/B3 for register instructions
  • 37/B7 for lui
  • 17/97 for auipc