Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

*W — RV64 word operations

addw  rd, rs1, rs2       # rd = sign_extend(rs1[31:0] + rs2[31:0])
addiw rd, rs1, imm12     # rd = sign_extend(rs1[31:0] + imm12)
subw  rd, rs1, rs2       # rd = sign_extend(rs1[31:0] - rs2[31:0])
sllw  rd, rs1, rs2       # rd = sign_extend(rs1[31:0] << rs2[4:0])
slliw rd, rs1, shamt5    # rd = sign_extend(rs1[31:0] << shamt5)
srlw  rd, rs1, rs2       # rd = sign_extend(rs1[31:0] >> rs2[4:0])   (zero-fill)
srliw rd, rs1, shamt5    # rd = sign_extend(rs1[31:0] >> shamt5)     (zero-fill)
sraw  rd, rs1, rs2       # rd = sign_extend(rs1[31:0] >>> rs2[4:0])  (arithmetic)
sraiw rd, rs1, shamt5    # rd = sign_extend(rs1[31:0] >>> shamt5)    (arithmetic)

RV64I only. These instructions treat their source operands as 32-bit values and write a sign-extended 64-bit result to rd — bit 31 of the result is copied into bits 63–32.

Shifts use only the low 5 bits of the shift amount (word-size shift), not 6 as in the 64-bit SLL/SRL/SRA.

When to use them

Use *W when source values are 32-bit and the result needs to be 32-bit. The sign-extension is free on most implementations; some even eliminate the operation entirely when the consumer also reads a word-width result.

You write …Instead of …Why
addiw rd, rs, 0slli + srai, or sext.w pseudosign-extend bit 31 to fill bits 63–32 (the + 0 is a no-op)
addw rd, rs1, rs2add + slli + sraisingle instruction, truncates then sign-extends inline
slliw rd, rs, 0slli + srai, or sext.w pseudoshift by zero leaves the low word unchanged, then sign-extends it
# 32-bit addition with overflow ignored (common in Java/.NET)
addw a0, a1, a2

# Sign-extend a 32-bit value to 64 bits
addiw a0, a1, 0

# 32-bit left shift
slliw a0, a1, 8

# 32-bit arithmetic right shift
sraiw a0, a1, 3

# Subtract using word width
subw  a0, a1, a2
subw  a0, a0, a3         # chained 32-bit subtract

Not available

There is no sltiw, sltuw, or sltiuw — comparison results are naturally 0/1 and need no truncation. There is also no andw, orw, or xorw. A full-width bitwise operation preserves the RV64 convention that 32-bit values are held sign-extended when both inputs already have that canonical form; if they do not, explicitly sign-extend the result when required.

x86 connection

Closest to 32-bit operand-size on x86-64 — e.g. add eax, ebx is 32-bit addition. The critical difference: x86 zero-extends the 32-bit result into RAX for most instructions, while RISC-V *W sign-extends. There is no x86 instruction that sign-extends a 32-bit arithmetic result into 64 bits as a side effect — movsxd (x86-64) sign-extends a move but cannot combine with an arithmetic operation.

Related: ADD / ADDI, SUB, SLL / SLLI, SRL, SRA.