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, rs2 | rd = rs1 + rs2 | |
sub rd, rs1, rs2 | rd = rs1 - rs2 | |
sll rd, rs1, rs2 | rd = rs1 << rs2 | shift left logical by register |
srl rd, rs1, rs2 | TODO | shift right logical by register |
sra rd, rs1, rs2 | TODO | shift right arithm. by register |
and rd, rs1, rs2 | rd = rs1 & rs2 | bitwise AND |
or rd, rs1, rs2 | rd = rs1 | rs2 | bitwise OR |
xor rd, rs1, rs2 | rd = rs1 ^ rs2 | bitwise XOR |
slt rd, rs1, rs2 | rd = ((int)rs1 < (int)rs2) | compare, set 1/0 |
sltu rd, rs1, rs2 | rd = ((uint)rs1 < (uint)rs2) | compare, set 1/0 |
addi rd, rs1, imm | rd = rs1 + (int32_t)imm | |
slli rd, rs1, imm | rd = 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, imm | rd = rs1 & imm | bitwise AND with immediate |
ori rd, rs1, imm | rd = rs1 | imm | bitwise OR with immediate |
xori rd, rs1, imm | rd = rs1 ^ imm | bitwise XOR with immediate |
slti rd, rs1, imm | rd = ((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, imm | rd = (imm << 12) | load upper immediate, set lower 12 bits to 0 |
auipc rd, imm | rd = 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] | rd | opcode | |
---|---|---|---|
lui | 01 101 11 | ||
auipc | 00 101 11 |
Encoding register instructions
Instructions with rs2 are R-type:
funct7 | rs2 | rs1 | funct3 | rd | opcode | |
---|---|---|---|---|---|---|
add | 0000000 | 000 | 01 100 11 | |||
sub | 0100000 | 000 | 01 100 11 | |||
sll | 0000000 | 001 | 01 100 11 | |||
slt | 0000000 | 010 | 01 100 11 | |||
sltu | 0000000 | 011 | 01 100 11 | |||
xor | 0000000 | 100 | 01 100 11 | |||
srl | 0000000 | 101 | 01 100 11 | |||
sra | 0100000 | 101 | 01 100 11 | |||
or | 0000000 | 110 | 01 100 11 | |||
and | 0000000 | 111 | 01 100 11 |
Encoding instructions with immediates
Everything else is I-type.
imm[11:5] | imm[4:0] | rs1 | funct3 | rd | opcode | |
---|---|---|---|---|---|---|
addi | 000 | 00 100 11 | ||||
slti | 010 | 00 100 11 | ||||
sltiu | 011 | 00 100 11 | ||||
xori | 100 | 00 100 11 | ||||
ori | 110 | 00 100 11 | ||||
andi | 111 | 00 100 11 | ||||
slli | 0000000 | shamt | 001 | 00 100 11 | ||
srli | 0000000 | shamt | 101 | 00 100 11 | ||
srai | 0100000 | shamt | 101 | 00 100 11 |
Least significant byte
13
/93
for instructions with immediates33
/B3
for register instructions37
/B7
for lui17
/97
for auipc