Unpredictable branches cost pipelines dearly, and secret-dependent branches leak timing. Zicond adds exactly two R-type instructions — conditional zeroing, not a full conditional move — from which branchless selects and conditional arithmetic compose:
Both carry syntactic dependencies from both sources to rd (no skipping reads, unlike Zimop), and under Zkt their timing must be independent of the data — the constant-time-crypto guarantee.
The cookbook
| Sequence | Len | |
|---|---|---|
| rd = (rc==0) ? rs1+rs2 : rs1 | czero.nez rd, rs2, rc · add rd, rs1, rd | 2 |
| rd = (rc!=0) ? rs1+rs2 : rs1 | czero.eqz rd, rs2, rc · add rd, rs1, rd | 2 |
| cond-sub / -or / -xor | Same shape — zero the second operand under the complementary condition, then sub/or/xor. | 2 |
| rd = (rc==0) ? rs1&rs2 : rs1 | and rd, rs1, rs2 · czero.eqz rtmp, rs1, rc · or rd, rd, rtmp — AND has no zero identity, so mask the fallback in instead. | 3 |
| rd = (rc==0) ? rs1 : rs2 (select) | czero.nez rd, rs1, rc · czero.eqz rtmp, rs2, rc · add rd, rd, rtmp — exactly one survives, add merges. | 3 + 1 temp |
Hardware Designer Notes
The datapath is an existence proof of cheapness: the zero-detect on rs2 already exists for branch comparisons, and the writeback mux already exists for load/ALU selection. Wiring them together under two funct3 codes is an afternoon of RTL.
Minimal Linux-boot hart MUST
- Implement both as single-cycle ALU ops: rd = (condition-test(rs2)) ? 0 : rs1 — an OR-reduce on rs2 and a 2:1 mux on the writeback path
- If you claim Zkt: verify the mux path has no value-dependent short-circuit timing
MAY simplify / trap-and-emulate
- Fuse the documented 2-instruction pairs (czero + add/sub/or/xor) into one internal micro-op — the sequences were designed to be fusion-friendly
- Skip Zicond on a minimal core (compilers fall back to branches) — but it is in RVA23, and the OR-reduce + mux is nearly free
Check yourself — Zicond
1.Express rd = (rc != 0) ? (rs1 + rs2) : rs1 with Zicond.
2.Why does a full conditional select need THREE instructions (two czeros + add)?
3.What extra guarantee do the czero instructions gain when Zkt is implemented?