Day 35: RV32I instruction formats: R / I / S / B / U / J
How instructions are encoded
Every RV32I instruction is exactly 32 bits, and falls into one of six formats by how it uses those bits: R (register-register: add, sub, and), I (register-immediate & loads: addi, lw, jalr), S (stores: sw), B (branches: beq, bne), U (upper immediates: lui, auipc), and J (jumps: jal). The opcode, funct3, and funct7 fields select the operation; rs1, rs2, rd name registers.
R: funct7[7] | rs2[5] | rs1[5] | funct3[3] | rd[5] | opcode[7]
I: imm[11:0] | rs1[5] | funct3[3] | rd[5] | opcode[7]
S: imm[11:5]|rs2[5]| rs1[5]| funct3[3] | imm[4:0]| opcode[7]
B: imm[12|10:5]|rs2| rs1 | funct3 | imm[4:1|11]| opcode
U: imm[31:12] | rd[5] | opcode[7]
J: imm[20|10:1|11|19:12] | rd[5] | opcode[7]
Note: B and J scramble the immediate bits to keep register fields
in fixed positions — a hardware convenience, decoded by wiring.The scrambled immediates are on purpose
B and J immediates look jumbled because RISC-V keeps rs1/rs2/rd and the sign bit in *fixed* bit positions across all formats. That lets the hardware start reading registers and sign-extending before it has fully decoded the opcode — a real speed and simplicity win you'll appreciate when you build the immediate-generation logic on Day 40.
Key terms
- opcode
- The 7-bit field selecting the broad instruction class and format.
- funct3 / funct7
- Sub-function fields that, with the opcode, pin down the exact operation.
- rs1 / rs2 / rd
- Source register 1, source register 2, and destination register fields.
- Immediate
- A constant encoded in the instruction, sign-extended to 32 bits before use.
- Instruction format
- One of R/I/S/B/U/J — the layout of the 32-bit instruction word.
Before moving on, you should be able to
Which instruction format does the store instruction sw use, and why does it differ from loads?