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/93for instructions with immediates33/B3for register instructions37/B7for lui17/97for auipc