C.ADD

RISC-V C.ADD 指令详解

指令手册CR format

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

指令语法

c.add rd, rs2
操作数说明
rd:完整 5 位目的/第一源字段,常规形式为 x1–x31。
rs2:完整 5 位第二源字段,常规形式为 x1–x31;rd=rs2 时两源读取同一旧值。
rs2=x0 选择 C.JALR/C.EBREAK;rd=x0 且 rs2 非零是 HINT,包括 Zihintntl 的 C.NTL 编码。
C压缩指令

扩展条件:RV32I/RV64I 的 C 扩展(或 Zca);16 位编码,IALIGN=16。动画按取指成功且无异步中断的条件展示架构效果。

指令行为说明

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 执行动画

RV32I/RV64I + C(或 Zca),16 位编码,IALIGN=16。

指令语法: c.add rd, rs2
执行环境
0x00000007 + 0x00000009 (mod 2^32) = 0x00000010
x10 ← 0x00000010; PC ← 0x00002002
16 位编码0x952E = 1001010100101110
funct4 [15..12]
1001
rd/rs1 [11..7]
01010 → x10
rs2 [6..2]
01011 → x11
op [1..0]
10
rd/rs1 → x10 = 0x00000007
rs2 → x11 = 0x00000009
C.ADD

还原压缩操作数

还原完整寄存器字段和立即数,并区分普通指令、HINT 与共享编码。

当前架构状态(提交前): x10=0x00000007; PC=0x00002000

这是架构效果的教学步骤,不代表处理器流水线或周期。

快速理解与检索要点

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。
16 位 CR 编码:funct4[15:12]=1001,rd/rs1[11:7] 和 rs2[6:2] 是完整 5 位字段,op[1:0]=10。普通加法仅写回低 XLEN 位,算术溢出不触发异常;rd=rs2 时使用同一旧值,结果覆盖该寄存器。

常见使用场景

寄存器操作

RV32I/RV64I + C/Zca,旧 x10=7、x11=9 时,c.add x10, x11 得到 x10=16,x11 不变;成功后 PC+2。

使用前检查清单

语法检查
  • 确认 RV32I/RV64I 的 C 或 Zca 可用;这些 16 位编码使用完整 5 位寄存器字段。
  • 常规 C.ADD 的 rd 和 rs2 均须非零;rs2=x0 选择 C.JALR/C.EBREAK。
语义检查
  • 区分普通写回、HINT 与共享编码,不把 HINT 当作普通算术结果。
  • 加法只写回低 XLEN 位;rd 与源重叠时读取同一旧值,成功后 PC+2。

容易混淆 / 常见误区

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。