18.3Source & Destination Register Listings

Part I Linux boot: required Vol. I (Unprivileged) pp. 89–95 · ~4 min read

  • accumulating csr

The PPO dependency rules (18.1, rules 9–13) are only as precise as the definition of which registers each instruction reads, writes, and carries dependencies between. Tables 13–22 pin that down for every RV64GC instruction. Rather than re-print ~200 uniform rows, here is the default rule plus the complete catalog of exceptions — which is exactly the data structure your LSU’s dependency tracker needs.

The default rule

An instruction’s sources are its rs1/rs2/rs3 fields, its destination is rd, and it carries a dependency from every source to every destination. x0 never counts as a source or destination.

Every ordinary computational instruction — ADDI, ADD, SUB, shifts, logic, MUL/DIV family, W forms, FSGNJ, FMV, FCLASS — follows it exactly. Memory instructions additionally tag their sources: rs1 is an address source (A); a store’s rs2 is a data source (D).

The exceptions (the whole point of §18.3)

Instructions that deviate from the default (the †/‡/footnote rows of Tables 13–22)
Sources → DestinationsDependency carry
Loads (LB/LH/LW/LD/LBU/LHU/LWU, FLW/FLD) †rs1ᴬ → rdNONE
Stores (SB/SH/SW/SD, FSW/FSD)rs1ᴬ, rs2ᴰ → (nothing)No destination — nothing to carry to
JALR †rs1 → rdNONE
Branchesrs1, rs2 → (nothing)They create CONTROL dependencies instead (PPO rule 11, stores only)
LR.W/D †rs1ᴬ → rdNONE (like a load)
SC.W/D †rs1ᴬ, rs2ᴰ → rd (only if successful)NONE; rd is a destination only on success
All AMOs (.W/.D) †rs1ᴬ, rs2ᴰ → rdNONE
FENCE / FENCE.I / ECALL / EBREAKno sources, no destinations
CSRRW ‡rs1, csr* → rd, csr (*csr not a source if rd=x0)rs1 → csr; csr → rd
CSRRS / CSRRC ‡rs1, csr → rd, csr* (*csr not a destination if rs1=x0)csr and rs1 → csr; csr → rd
CSRRWI ‡csr* → rd, csr (*unless rd=x0)csr → rd
CSRRSI / CSRRCI ‡csr → rd, csr* (*unless uimm=0)csr → rd and csr
FP computational (FADD…FSQRT, FMA family) rs1[, rs2[, rs3]], frm* → rd (*frm a source only when rm=111)Default carry, plus flag accumulation
FP compares/min/max/convertssources → rd, flags accumulate (NV, NX as applicable)Default + accumulate
Dotted-underlined cells have explanations — click one.

Key: ᴬ address source · ᴰ data source · † carries no src→dst dependency · ‡ carries exactly what’s listed.

Hardware Designer Notes

For an out-of-order design, this section IS the rename-stage specification of memory-model dependencies: the † rows tell you which producer→consumer edges are ordering-relevant (none through loads/AMOs themselves), and the A/D tags tell you which operand of a memory op each incoming edge constrains. Practical test: the xor t1,a0,a0; add t2,t3,t1; lw …,(t2) fake-dependency idiom must block address issue — if your zero-detection or move-elimination optimizes it away in the ordering domain, you’ve broken PPO rule 9 while keeping dataflow correct. Keep value optimization and ordering tracking separate.

Minimal Linux-boot hart MUST

  • Track address/data source distinction in the LSU — PPO rules 9/10/13 key on it
  • Treat consumer-of-load-rd as dependent on the load even though loads carry nothing themselves
  • Model the CSR carry rules exactly (rs1→csr but not rs1→rd for CSRRW) if you reorder around CSR ops at all
  • Honor frm as a source under rm=111 — a write to frm must order before dynamic-rounding FP ops

MAY simplify / trap-and-emulate

  • Ignore all of this in an in-order core — program order subsumes every syntactic dependency
  • Let FP flag updates accumulate out of order (they carry only flag→flag)

Check yourself — dependency listings

1.lw t0,(a0); sw t1,0(t0). Then: lw t0,(a0); add t2,t0,zero; lw t3,(t2). Which orderings hold?

2.Why is a successful SC's rd architecturally interesting for dependencies?

3.A sequence of FADD.S instructions all update the NX flag in fflags. Do they serialize on it?

4.When is frm a source register of an FP instruction?

4 questions