C.ADD 可以使用哪些寄存器?
CR 格式的 rd 和 rs2 是完整的 5 位字段,因此编码可引用 x0-x31 中的寄存器;但常规 C.ADD 语义要求 rd 与 rs2 都不为 x0。
常规 C.ADD 将 rd 与 rs2 相加,结果写回 rd。CR 格式;rd 与 rs2 都必须非零。
C.ADD(CR 格式,可访问全部 32 个寄存器)将 rd 与 rs2 相加并写回 rd,等价于 add rd, rd, rs2。常规 C.ADD 要求 rd≠x0 且 rs2≠x0:rs2=x0 时,rd≠x0 编码为 C.JALR,rd=x0 编码为 C.EBREAK。rs2 非零且 rd=x0 的编码通常是 HINT;其中 rs2=x2-x5 在实现 Zihintntl 扩展时分别编码为 C.NTL.P1、C.NTL.PALL、C.NTL.S1、C.NTL.ALL。
按实际 CR 或 CI 16 位编码解码,并分清普通指令、HINT 与共享编码。
funct4、rd/rs1、rs2 与 op 字段共同识别这条 16 位 C.ADD 指令。
0x952E = 1001010100101110x[rd] ← old x[rd] + x[rs2] (仅写回低 XLEN 位)
rd 同时是第一个源和目的寄存器:必须先保留旧 x[rd],最后才用结果覆盖它。
funct4=1001、op=10;rd/rs1=x10,rs2=x11。rd 和 rs2 都非 x0,因此这是普通 C.ADD。
尚未读取寄存器;x[rd] 仍不能被覆盖。
尚未计算;先读取两个源值。
尚未写回;当前架构可见的 x[rd] 仍是旧快照。
动画只展示官方定义的解码、寄存器读取、算术和架构状态,不表示实现的流水线、缓存、预测或时序。
C.ADD 使用 CR 格式,把 rd 与 rs2 相加后写回 rd;常规 C.ADD 要求 rd 与 rs2 都不为 x0。
结合 «c.add x10, x11 # x10 += x11» 等实际代码理解该场景。
CR 格式的 rd 和 rs2 是完整的 5 位字段,因此编码可引用 x0-x31 中的寄存器;但常规 C.ADD 语义要求 rd 与 rs2 都不为 x0。