2.1-4Programmers' Model, Instruction Formats & Integer Computation

Part I Linux boot: required Vol. I (Unprivileged) pp. 23–29 · ~8 min read

  • x0 (zero register)
  • program counter (pc)
  • calling convention
  • pseudoinstruction
  • shamt
  • reserved instruction

RV32I is the mandatory core: 40 unique instructions, deliberately small enough that a minimal implementation can shrink further (trap all SYSTEM instructions to one handler, implement FENCE as a NOP) yet complete enough to be a serious compiler and OS target. Almost everything else in this book is layered on the decisions made in these seven pages.

2.1 The programmers’ model

The unprivileged integer state is exactly 33 registers: x0x31, each XLEN = 32 bits wide, plus the program counter . x0 is hardwired to zero — the architectural constant that turns MV, NOT, NOP and unconditional jumps into special cases of ordinary instructions.

Crucially, the architecture dedicates no stack pointer and no link register — any x register works. Those roles come from the standard calling convention , and hardware is explicitly invited to exploit them:

Base integer register state (Table 2) + standard ABI roles
ABI nameConvention roleHardware significance
x0zeroConstant 0Hardwired; rd=x0 encodings become HINT space
x1raReturn addressRAS push/pop hint register
x2spStack pointerC extension assumes it
x5t0Alternate link registerSecond RAS hint register
x3, x4gp, tpGlobal / thread pointerNo hardware meaning in the base ISA
x6–x31t1…, s0…, a0…Temporaries, saved regs, argumentsUniform — no special treatment anywhere in RV32I
pcCurrent instruction addressOnly readable via AUIPC/JAL
Dotted-underlined cells have explanations — click one.

2.2 The four core formats

Everything 32-bit in the base ISA is one of four formats — R, I, S, U — and the geometry is the point:

funct73125rs22420rs11915funct31412rd117opcode60R-Type
Click a field for its role.
imm[11:0]3120rs11915funct31412rd117opcode60I-Type
Click a field for its role.
imm[11:5]3125rs22420rs11915funct31412imm[4:0]117opcode60S-Type
Click a field for its role.
imm[31:12]3112rd117opcode60U-Type
Click a field for its role.

Two rules you can build a decoder around:

  1. Register specifiers never move. rs1 = [19:15], rs2 = [24:20], rd = [11:7], in every format that has them. Your regfile read can begin before format decode finishes.
  2. The immediate sign bit is always inst[31], so sign extension runs in parallel with everything else.

IALIGN = 32 in the base ISA: a taken branch or jump to a non-4-byte-aligned target raises instruction-address-misaligned — reported on the branch or jump, not the target (a not-taken branch never faults). Decoding a reserved instruction is UNSPECIFIED.

2.3 B and J: immediates that rotate instead of shift

Branches need offsets in multiples of 2, jumps likewise. Conventional ISAs shift the whole immediate left by one in hardware; RISC-V instead rewires one bit per format and keeps everything else in place. Explore the actual wiring — this is Figure 1 made clickable:

instruction bits 31…03130:2524:2120immediate bits 11…01110:54:10sign-extension always from inst[31]
Click any segment to see where it comes from and why it lives there.

The payoff, per the architects: immediate-mux fanout roughly halved in the simplest implementations, at the cost of a scrambled-looking encoding that only bothers humans and JIT compilers.

2.4 Integer computational instructions

All computation is XLEN-bit, register-immediate (I-type) or register-register (R-type), destination rd. No arithmetic exceptions exist — overflow is ignored, results are the low XLEN bits, and overflow checks are short branch sequences (add t0,t1,t2; bltu t0,t1,overflow for unsigned). There is no flags register anywhere in RISC-V.

Register-immediate: ADDI (also the canonical MV), SLTI/SLTIU (compare against the sign-extended immediate — note SLTIU rd,rs,1 is SEQZ), ANDI/ORI/XORI (XORI rd,rs,-1 is NOT). Constant shifts specialize I-type: the shamt lives in imm[4:0] and bit 30 selects the right-shift type:

031130000002925shamt2420rs119151011412rd117OP-IMM60SRAI
Click a field for its role.

Upper-immediate pair: LUI rd, imm20 writes imm20 ≪ 12 (low 12 bits zero); AUIPC rd, imm20 adds that shifted value to its own address. Together with 12-bit I/S immediates they make any 32-bit constant a two-instruction job and any 32-bit PC-relative address reachable: AUIPC+JALR for calls, AUIPC+load/store for data. AUIPC rd, 0 is the idiomatic “give me my PC”.

Register-register: ADD/SUB, SLT/SLTU (SLTU rd,x0,rs2 = SNEZ), AND/OR/XOR, SLL/SRL/SRA (shift amount = low 5 bits of rs2). funct7 bit 30 again selects SUB/SRA.

NOP is pseudoinstruction ADDI x0, x0, 0 — chosen canonically so decoders can recognize (or eliminate) one specific encoding, and because an ADDI costs the fewest resources: one register read, executable by any address-generation adder.

Hardware Designer Notes

The format geometry is a gift to your decoder: two fixed invariants (register slices, sign bit) remove the format mux from the two paths that matter — regfile index and sign extension. The immediate “scrambling” is where the saved multiplexers went; resist the urge to normalize it in an intermediate representation on the critical path. Bit 30 doing double duty (SUB/SRA, SRLI/SRAI) means your ALU op-select is funct3 plus exactly one extra wire.

Minimal Linux-boot hart MUST

  • Fix rs1/rs2/rd extraction to constant bit slices — no format conditioning
  • Sign-extend all immediates from inst[31]; implement the B/J bit rotation as wiring, not a shifter
  • Raise instruction-address-misaligned on the taken branch/jump itself (target misaligned, IALIGN=32)
  • No flags, no arithmetic exceptions — the integer ALU writes back unconditionally

MAY simplify / trap-and-emulate

  • Decode-eliminate the canonical NOP (and only it) for zero-cost padding
  • Special-case x0 as reads-as-zero in the regfile or bypass network — either works
  • Treat reserved encodings as illegal-instruction (UNSPECIFIED allows it; many platforms require it)

Check yourself — registers, formats & computation

1.Why do rs1, rs2 and rd occupy the same bit positions in every RV32I format?

2.Your decoder wants to start sign-extending the immediate before it even knows the instruction format. Legal?

3.ADD overflows. What does the hardware do?

4.How does hardware tell SRAI from SRLI, given both are OP-IMM shifts?

5.What does the sequence AUIPC t0, 0 give you, and why prefer it over JAL +4 tricks?

5 questions