30.9.34-41Bitmanip VI: rori — sh2add (Reference)

Part III Linux boot: recommended Vol. I (Unprivileged) pp. 261–268 · ~2 min read

Immediate rotates, the sign-extenders, and the first shift-adds.

rori through sh2add
SemanticsEncodingIn
rori rd, rs1, shamtRotate right by a constant — the SHA-2 sigma workhorse.OP-IMM 0110000 / 101Zbb, Zbkb
roriw rd, rs1, shamt (RV64)Rotate within the low 32 bits (wrap at bit 31), sign-extend — 32-bit crypto on 64-bit cores.OP-IMM-32 0110000 / 101Zbb, Zbkb
rorw rd, rs1, rs2 (RV64)Register-amount 32-bit rotate.OP-32 0110000 / 101Zbb, Zbkb
sext.b rd, rsSign-extend the low byte — replaces the slli/srai pair.OP-IMM funct12 0110000_00100 / 001Zbb
sext.h rd, rsSign-extend the low halfword.OP-IMM funct12 0110000_00101 / 001Zbb
sh1add rd, rs1, rs2rd = rs2 + (rs1 << 1) — halfword-array indexing.OP 0010000 / 010Zba
sh1add.uw rd, rs1, rs2 (RV64)rd = rs2 + (zext32(rs1) << 1) — unsigned-word index.OP-32 0010000 / 010Zba
sh2add rd, rs1, rs2rd = rs2 + (rs1 << 2) — the int/float array indexer, likely the most-executed Zba instruction.OP 0010000 / 100Zba
Dotted-underlined cells have explanations — click one.

The shNadd family’s encoding economy: one funct7 (0010000), the shift amount riding in funct3 (010/100/110), with the .uw twins at the same points in OP-32. Compilers emit these from any indexed access — a[i] with 2/4/8-byte elements — turning the slli-then-add pair into one instruction on the adder’s existing timing.

Hardware Designer Notes

sh2add deserves its own performance counter: measure it on pointer-heavy code and you’ll find it firing once per several loads. That’s the Zba pitch in one number.

Minimal Linux-boot hart MUST

  • Distinguish the two rotate wrap modes (bit 63 vs bit 31 + sign-extension) in the shared rotator — the w-forms are separate permutations, not truncations
  • Wire sext.b/sext.h as writeback extend muxes (the load unit’s logic, applied to an ALU result)

MAY simplify / trap-and-emulate

  • Emit rol-immediate as rori with the complement amount in the assembler (why no roli exists)

Check yourself — rori, sext, shNadd

1.sext.b previously took two instructions. Which, and why does one instruction beat them beyond count?

2.sh1add/sh2add/sh3add share funct7 0010000. How is the shift amount encoded?

3.Why do rori (RV64) and roriw both exist when rori can encode any rotation?

3 questions