C.ADD

RISC-V C.ADD 指令详解

指令手册CR format

常规 C.ADD 将 rd 与 rs2 相加,结果写回 rd。CR 格式;rd 与 rs2 都必须非零。

指令语法

c.add rd, rs2
操作数说明
本指令为 CR format 格式,请根据汇编语法确认各操作数位置。
C压缩指令

指令行为说明

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。

C.ADD 指令解析与执行动画

按实际 CR 或 CI 16 位编码解码,并分清普通指令、HINT 与共享编码。

当前步骤

步骤 1:识别 C.ADD

funct4、rd/rs1、rs2 与 op 字段共同识别这条 16 位 C.ADD 指令。

指令语法
执行环境
16 位编码
0x952E = 1001010100101110
funct4 [15..12]
1001
rd/rs1 [11..7]
01010
rs2 [6..2]
01011
op [1..0]
10
C.ADD 执行过程

x[rd] ← old x[rd] + x[rs2] (仅写回低 XLEN 位)

rd 同时是第一个源和目的寄存器:必须先保留旧 x[rd],最后才用结果覆盖它。

1. 解码 CR 字段

funct4=1001、op=10;rd/rs1=x10,rs2=x11。rd 和 rs2 都非 x0,因此这是普通 C.ADD。

2. 读取并冻结写回前快照

尚未读取寄存器;x[rd] 仍不能被覆盖。

3. 按 XLEN 宽度相加

尚未计算;先读取两个源值。

4. 写回 rd

尚未写回;当前架构可见的 x[rd] 仍是旧快照。

动画只展示官方定义的解码、寄存器读取、算术和架构状态,不表示实现的流水线、缓存、预测或时序。

快速理解与检索要点

C.ADD 使用 CR 格式,把 rd 与 rs2 相加后写回 rd;常规 C.ADD 要求 rd 与 rs2 都不为 x0。

C.ADD 展开为 add rd, rd, rs2,使用完整的 5 位 rd 和 rs2 寄存器字段。
rs2=x0 时,rd≠x0 解码为 C.JALR,rd=x0 解码为 C.EBREAK。rd=x0、rs2 非零时通常为 HINT;但启用 Zihintntl 时,rs2=x2-x5 分别是 C.NTL.P1/PALL/S1/ALL。

常见使用场景

寄存器操作

结合 «c.add x10, x11 # x10 += x11» 等实际代码理解该场景。

使用前检查清单

语法检查
  • 确认当前指令格式为 CR format。
  • 确认操作数排列顺序与示例一致。
语义检查
  • 确认目标寄存器用途和调用约定兼容。
  • 确认该指令不是伪指令展开后的底层形式。

容易混淆 / 常见误区

rs2=x0 时不是 C.ADD:rd≠x0 为 C.JALR,rd=x0 为 C.EBREAK;rd=x0、rs2=x2-x5 在 Zihintntl 下是 C.NTL 编码。
CR格式可访问全部32个寄存器(不同于C.AND等CA格式指令仅限x8-x15)

常见问题

C.ADD 可以使用哪些寄存器?

CR 格式的 rd 和 rs2 是完整的 5 位字段,因此编码可引用 x0-x31 中的寄存器;但常规 C.ADD 语义要求 rd 与 rs2 都不为 x0。