Find-first-set, the comparison selects, and the string-processing special.
| Semantics | Encoding | In | |
|---|---|---|---|
| ctz rd, rs | Count trailing zeros; ctz(0) = XLEN, fully defined — no guard branch needed. THE find-first-set of scheduler bitmaps and allocators. | OP-IMM funct12 0110000_00001 / 001 | Zbb |
| ctzw rd, rs (RV64) | Trailing zeros of the low word; ctzw(0) = 32. | OP-IMM-32, same funct12 | Zbb |
| min rd, rs1, rs2 | Signed minimum. | OP 0000101 / 100 | Zbb |
| minu rd, rs1, rs2 | Unsigned minimum. | OP 0000101 / 101 | Zbb |
| max rd, rs1, rs2 | Signed maximum — clamping, sorting networks, branch-free saturation bounds. | OP 0000101 / 110 | Zbb |
| maxu rd, rs1, rs2 | Unsigned maximum. | OP 0000101 / 111 | Zbb |
| orc.b rd, rs | Each output byte = 0x00 if its input byte was zero, else 0xFF. | OP-IMM funct12 0010100_00111 / 101 | Zbb |
| orn rd, rs1, rs2 | rd = rs1 | ~rs2 — OR with inverted operand. | OP 0100000 / 110 | Zbb, Zbkb |
Note the encoding economy: min/max share clmul’s funct7 (0000101) across funct3 100–111 — the “MINMAX/CLMUL” row of the opcode map — and orn sits beside andn/xnor under the subtraction funct7 (0100000), because all three borrow the subtractor’s rs2 inverter.
Hardware Designer Notes
This page is why Zbb is mandatory in RVA23: strlen/strcpy/memchr (orc.b + ctz), clamps (min/max), and bitmap scans (ctz) are the kernel and libc’s daily bread, and every instruction here is sub-ALU-cost.
Minimal Linux-boot hart MUST
- ctz shares the clz scan tree (bit-reverse the input or build a trailing tree); keep the zero-input constants exact (XLEN / 32)
- min/max: one subtract-compare (you have it) steering a 2:1 writeback mux, with the signed/unsigned flag from funct3 bit 0
MAY simplify / trap-and-emulate
- Implement orc.b as eight parallel 8-input ORs fanned back out — a single gate level per lane
- Fuse orc.b + ctz when your decoder sees the strlen pair back-to-back
Check yourself — ctz, min/max, orc.b
1.How does orc.b accelerate strlen?
2.Why did min/max/minu/maxu make it into Zbb when a branch or Zicond sequence can compute them?
3.ctz(0) returns what, and why does the definedness matter?