30.1-1Bitmanip I: The Zb* Family & Zba Address Generation

Part III Linux boot: recommended Vol. I (Unprivileged) pp. 221–228 · ~3 min read

Seven small extensions, grouped by use case, sharing one property: mnemonics and encodings are independent of extension membership, so overlapping instructions (ror lives in Zbb and Zbkb) cost nothing twice. B = Zba + Zbb + Zbs — the general-purpose trio mandated by RVA23.

The Zb* map
InstructionsUse case
Zba — address generationadd.uw, sh1add/sh2add/sh3add (+.uw forms), slli.uwbase + scaled index in one instruction.
Zbb — basic bitmanipandn/orn/xnor, clz/ctz/cpop (+w), min/max[u], sext.b/h, zext.h, rol/ror/rori (+w), orc.b, rev8The compiler’s daily drivers: strlen, byte swaps, idiom compression.
Zbs — single-bitbset/bclr/binv/bext + immediate formsBitfield and flag manipulation by index.
Zbc — carry-less multiplyclmul/clmulh/clmulrGF(2) polynomial products: CRCs, GCM.
Zbkb / Zbkc / Zbkx — crypto subsetsRotates + logical-negate + pack/packh/packw + brev8 + rev8 + zip/unzip (RV32); clmul/clmulh; xperm4/xperm8Cipher permutations, GHASH, constant-time in-register SBoxes.
Dotted-underlined cells have explanations — click one.

Three suffix conventions to internalize: w (no dot, RV64) = operate on the low 32 bits as signed, sign-extend the 32-bit result; .uw = one operand is the zero-extended low word, the operation itself is full-XLEN; .b/.h/.w = input narrowed to 8/16/32 bits, result extended per instruction.

Zba — the address generators

Array indexing is base + (index << log2(size)). Zba fuses it: sh1add/sh2add/sh3add rd, rs1, rs2 compute rs2 + (rs1 << 1/2/3) — shifts capped at 3 because those mux legs add nothing to the adder’s critical path. The .uw forms first zero-extend rs1’s low word (unsigned 32-bit indices in 64-bit address spaces — every JavaScript array, every uint32 loop variable), and slli.uw covers wider scaling.

00001003125rs22420rs119150001412rd117011101160add.uw (OP-32, the Zba flagship)
Click a field for its role.

Hardware Designer Notes

Zba is the highest instructions-per-gate win in the whole catalog: three mux legs buy back one instruction from nearly every array-access sequence the compiler emits. If you benchmark one thing from this chapter, benchmark sh2add on pointer-chasing code.

Minimal Linux-boot hart MUST

  • For Zba: three extra B-input mux legs on the main adder (<<1, <<2, <<3) plus the .uw zero-extend mux — verify timing, the whole point is not stretching the adder path
  • Keep decode extension-agnostic: one entry per instruction regardless of how many Zb* sets you advertise

MAY simplify / trap-and-emulate

  • Implement Zba+Zbb+Zbs (= B) as the package — RVA23 mandates them and compilers emit them freely at -march defaults
  • Defer Zbc/Zbkx unless crypto throughput matters; Zbkb mostly falls out of Zbb + a few pack/zip gates

Check yourself — bitmanip overview & Zba

1.Why do the shift-and-add instructions stop at a shift of 3?

2.What does the .uw suffix mean, and what is zext.w an alias for?

3.An instruction like ror appears in both Zbb and Zbkb. What does that overlap mean for hardware?

3 questions