C.ADD

RISC-V C.ADD Instruction Details

Instruction ManualCR format

Regular C.ADD adds rd and rs2 and writes the result to rd. CR format; both rd and rs2 must be nonzero.

Instruction Syntax

c.add rd, rs2
Operand Breakdown
rd: full 5-bit destination/first-source field, x1–x31 for the regular form.
rs2: full 5-bit second-source field, x1–x31 for the regular form; rd=rs2 reads one old value for both sources.
rs2=x0 selects C.JALR/C.EBREAK; rd=x0 with nonzero rs2 is a HINT, including Zihintntl C.NTL encodings.
CCompressed Instruction

Extension condition: C (or Zca) on RV32I/RV64I; 16-bit encoding, IALIGN=16. The animation assumes successful instruction fetch and no asynchronous interrupt.

Instruction Behavior

C.ADD (CR format, with access to all 32 registers) adds rd and rs2 and writes the result to rd, equivalent to add rd, rd, rs2. Regular C.ADD requires rd!=x0 and rs2!=x0: with rs2=x0, rd!=x0 encodes C.JALR and rd=x0 encodes C.EBREAK. With nonzero rs2 and rd=x0, the encoding is normally a HINT; when Zihintntl is implemented, rs2=x2-x5 instead encode C.NTL.P1, C.NTL.PALL, C.NTL.S1, and C.NTL.ALL.

C.ADD Execution Animation

RV32I/RV64I + C (or Zca), 16-bit encoding, IALIGN=16.

Instruction Syntax: c.add rd, rs2
Execution Context
0x00000007 + 0x00000009 (mod 2^32) = 0x00000010
x10 ← 0x00000010; PC ← 0x00002002
16-bit Encoding0x952E = 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

Restore compressed operands

Restore full register fields and the immediate, distinguishing ordinary instructions, HINTs, and shared encodings.

Current architectural state (before commit): x10=0x00000007; PC=0x00002000

These are teaching steps for architectural effects, not processor pipeline stages or cycles.

Quick Understanding & Search Notes

C.ADD uses the CR format and writes rd + rs2 back to rd; the regular C.ADD form requires both rd and rs2 not to be x0.

C.ADD expands to add rd, rd, rs2 and uses full 5-bit rd and rs2 register fields.
With rs2=x0, rd!=x0 decodes as C.JALR and rd=x0 as C.EBREAK. With rd=x0 and nonzero rs2, the encoding is normally a HINT; under Zihintntl, rs2=x2-x5 instead encode C.NTL.P1/PALL/S1/ALL.
16-bit CR encoding: funct4[15:12]=1001, full 5-bit rd/rs1[11:7] and rs2[6:2], op[1:0]=10. Ordinary addition writes only the low XLEN bits without an arithmetic-overflow exception; rd=rs2 uses one old value and overwrites that register.

Common Usage Scenarios

Basic Arithmetic

RV32I/RV64I + C/Zca, old x10=7 and x11=9: c.add x10, x11 yields x10=16, leaves x11 unchanged, and advances PC by 2.

Pre-Use Checklist

Syntax Check
  • Verify C or Zca on RV32I/RV64I; these 16-bit encodings use full 5-bit register fields.
  • Regular C.ADD requires nonzero rd and rs2; rs2=x0 selects C.JALR/C.EBREAK.
Semantic Check
  • Distinguish ordinary writeback, HINTs, and shared encodings; do not present a HINT as ordinary arithmetic.
  • Addition writes only the low XLEN bits; overlapping registers use one old value, and successful execution advances PC by 2.

Pitfalls / Common Confusions

rs2=x0 is not C.ADD: rd!=x0 encodes C.JALR and rd=x0 encodes C.EBREAK; rd=x0 with rs2=x2-x5 is a C.NTL encoding under Zihintntl.
CR format allows all 32 registers (unlike C.AND etc. in CA format limited to x8-x15)

FAQ

Which registers can C.ADD use?

The CR-format rd and rs2 fields are full 5-bit fields, so the encoding can name registers x0-x31; regular C.ADD semantics require both rd and rs2 not to be x0.