4.1-4RV64I: Widening the Base to 64 Bits

Part I Linux boot: required Vol. I (Unprivileged) pp. 41–44 · ~5 min read

  • sign-extension invariant
  • w-suffix instruction
  • lwu

RV64I is RV32I with XLEN = 64 — same 31 general registers plus x0, same formats, same opcodes — described purely as a delta. For a Linux-bootable core this is your base ISA, and the entire delta hangs on one idea:

4.1–4.2 The sign-extension invariant

Every 32-bit value in a 64-bit register is kept sign-extended — bits 63:32 always replicate bit 31, even for unsigned values. The invariant buys a remarkable amount for free:

  • signed ↔ unsigned 32-bit conversion: no-op;
  • signed 32 → signed 64 widening: no-op;
  • 64-bit SLTU and unsigned branches work unchanged on 32-bit data;
  • 64-bit logical ops preserve the invariant by construction.

What it can’t make free are operations where bit 31 changes: 32-bit adds, subs, and shifts. Those get W-suffix variants under two new major opcodes (OP-IMM-32, OP-32): they ignore the upper 32 input bits, compute a 32-bit result, and sign-extend it to 64.

rs1[63:32], rs2[63:32] — ignoredrs1[31:0] op rs2[31:0]rd[63:32] = replicate result[31]rd[31:0] = result[31:0]

A W instruction in a 64-bit datapath: the normal ALU plus one bit-31-replication mux at writeback — not a second 32-bit ALU.

The full RV64I delta:

Instructions added or changed by RV64I
SemanticsHardware note
ADDIWrd = sext32(rs1[31:0] + imm)ADDIW rd,rs,0 = SEXT.W
ADDW / SUBWrd = sext32(rs1[31:0] ± rs2[31:0])OP-32; funct7 bit 30 selects SUB, exactly as in OP
SLLIW / SRLIW / SRAIW32-bit constant shifts, shamt[4:0]imm[5] ≠ 0 reserved
SLLW / SRLW / SRAW32-bit register shifts, amount = rs2[4:0]The 64-bit forms read rs2[5:0] — one extra bit of shifter control
SLLI / SRLI / SRAI (widened)64-bit constant shifts, shamt[5:0]Same opcodes as RV32I — imm[5] joins the shamt; bit 30 still selects arithmetic
LD / SD64-bit load / storeThe doubleword datapath width everything else assumes
LW / LWULW sign-extends; LWU zero-extendsLW changes meaning vs RV32
LUI / AUIPC (widened)32-bit result sign-extended to 64Pair range [−2³¹−2¹¹, 2³¹−2¹¹−1]
Dotted-underlined cells have explanations — click one.

The W constant shifts, concretely:

0100003126025shamt[4:0]2420rs119151011412rd117OP-IMM-3260SRAIW
Click a field for its role.

RV64I’s HINT space (Table 6) is the RV32I map plus rd=x0 encodings of all the W instructions in the future-standard pool; NTL.*, PAUSE, and the semihosting markers sit at the same code points, and the custom rows grow slightly (6-bit shamts).

Hardware Designer Notes

A Linux-capable hart is RV64: this page is your integer datapath spec. The practical checklist is short — one writeback mux for sign-extension, one extra shamt bit, LD/SD/LWU in the load/store unit — but the invariant has a verification bite: any path that writes a register with bits 63:32 ≠ replicated bit 31 while software believes it holds a 32-bit value is a silent miscompare later, in code far from the bug. Assert the invariant on W-instruction results in your testbench.

Minimal Linux-boot hart MUST

  • Implement W forms as low-32 operate + bit-31 replication at writeback — full-width register writes, never partial
  • Widen shifter control: 64-bit shifts consume shamt[5:0] / rs2[5:0]; W shifts consume [4:0] only
  • Sign-extend LW and LUI/AUIPC results; add LWU as the zero-extend path

MAY simplify / trap-and-emulate

  • Trap or accept SLLIW/SRLIW/SRAIW with imm[5]=1 — reserved, your documented choice
  • Fuse ADDIW rd,rs,0 (SEXT.W) with a preceding W-producer if your pipeline benefits

Check yourself — RV64I

1.On RV64, a register holds the unsigned 32-bit value 0x8000_0000 per the calling convention. What are bits 63:32?

2.What does ADDW actually compute in hardware?

3.Your decoder sees SLLIW with shamt bit 5 set. What does the current spec say?

4.Why does RV64I need LWU when RV32I never needed unsigned word loads?

4 questions