CM.POP

RISC-V CM.POP Instruction Details

Instruction ManualC2 (Zcmp CMPP)

Restore the ra and 0 to 12 s-registers selected by reg_list, then adjust sp

Instruction Syntax

cm.pop {reg_list}, stack_adj
Operand Breakdown
RV32/RV64 Zcmp requires Zca and conflicts with Zcd; 16-bit CMPP, without x8–x15 compact-register fields.
rlist selects ra/x1 and a contiguous list of s0/x8, s1/x9, s2–s11/x18–x27; 0–3 are reserved, and RV32E permits only 4–6.
rlist=15 includes both s10/s11; stopping at s10 is not encodable. stack_adj is the list/XLEN size rounded up to 16 bytes, plus spimm×16 (spimm=0–3).
Pseudocode restores selected registers downward from old sp+stack_adj-XLEN/8; on success sp increases by stack_adj.
No implicit ret or a0 zeroing; no direct single 32-bit equivalent encoding exists.
Accesses may reorder, group or repeat, with partial effects before faults; the final section commits only when the whole instruction can commit.
ZcmpStack & FunctionsCompressed Instruction

Instruction Behavior

CM.POP (Zcmp) pops registers in {reg_list} from stack and increments sp by stack_adj. Used with CM.PUSH. Note: CM.POP does NOT execute ret — only restores registers and deallocates stack frame. Reuses c.fsdsp encoding, incompatible with Zcd. Part of Zcmp, depends on Zca.

CM.POP Decode & Execute Animation

Shows only Zcmp architectural sequences and conditions; access order, grouping, or replay does not imply implementation detail.

cm.pop {reg_list}, stack_adj
Execution context

Zcmp depends on Zca and is incompatible with Zcd. Correct execution requires idempotent memory at sp; RV32E permits rlist=4-6 only. Values are pre-store registers or successfully loaded memory values; complete assumes the EEI permits all accesses, not that every address succeeds.

sp=0x00001000, rlist=7 -> s2/x18 <- mem32[0x0000103C]=0x00000030; s1/x9 <- mem32[0x00001038]=0x00000020; s0/x8 <- mem32[0x00001034]=0x00000010; ra/x1 <- mem32[0x00001030]=0x00002001; sp <- 0x00001040
16-bit encoding fields
15..13
funct3
101
12..8
fixed
11010
7..4
rlist
0111
3..2
spimm
11
1..0
op
10
rlist=7 restores {ra/x1, s0/x8, s1/x9, s2/x18}; stack_adj_base=16; stack_adj=16+3×16=64 bytes.
Pseudocode address mapping: s2/x18 <- mem32[0x0000103C]=0x00000030; s1/x9 <- mem32[0x00001038]=0x00000020; s0/x8 <- mem32[0x00001034]=0x00000010; ra/x1 <- mem32[0x00001030]=0x00002001. The actual loads can occur in any order, be grouped, or repeat; sp' = 0x00001000 + 64 = 0x00001040.
s2/x18 <- mem32[0x0000103C]=0x00000030; s1/x9 <- mem32[0x00001038]=0x00000020; s0/x8 <- mem32[0x00001034]=0x00000010; ra/x1 <- mem32[0x00001030]=0x00002001; sp <- 0x00001040
Architectural state has not been committed.

Quick Understanding & Search Notes

Load the listed registers from the stack, then add stack_adj to sp.

RV32/RV64 Zcmp requires Zca and conflicts with Zcd. 16-bit CMPP: bits[15:13]=101, [12:8]=11010, rlist=[7:4], spimm=[3:2], [1:0]=10.
rlist=4 selects {ra}; 5–14 successively add s0 through s9; 15 selects {ra,s0-s11}, skipping {ra,s0-s10}. Values 0–3 are reserved; RV32E permits only 4–6.
stack_adj_base = ceil(register_count × XLEN / 8 / 16) × 16; stack_adj = base + spimm × 16, spimm=0–3. RV32E uses base=16.
Load selected registers in descending register-number order, starting at old sp + stack_adj - XLEN/8 and subtracting XLEN/8 per register. No direct single 32-bit equivalent encoding exists.
Accesses may reorder, group, or repeat; correct execution requires idempotent memory. A precise fault may follow partial register loads; final sp commit atomically only when the entire instruction can commit.

Common Usage Scenarios

Function epilogue

RV32I Zcmp, accesses complete: {ra,s0-s2} occupies 16 bytes; stack_adj=64 encodes rlist=7, spimm=3. PUSH saves below old sp then sp-=64; POP forms restore from old sp+48 through old sp+60 then sp+=64. Return forms use restored ra; POPRETZ also zeros a0.

Pre-Use Checklist

Syntax Check
  • RV32/RV64 Zcmp requires Zca and conflicts with Zcd; 16-bit CMPP, without x8–x15 compact-register fields.
  • rlist selects ra/x1 and a contiguous list of s0/x8, s1/x9, s2–s11/x18–x27; 0–3 are reserved, and RV32E permits only 4–6.
Semantic Check
  • rlist=15 includes both s10/s11; stopping at s10 is not encodable. stack_adj is the list/XLEN size rounded up to 16 bytes, plus spimm×16 (spimm=0–3).
  • Pseudocode restores selected registers downward from old sp+stack_adj-XLEN/8; on success sp increases by stack_adj.
  • No implicit ret or a0 zeroing; no direct single 32-bit equivalent encoding exists.
  • Accesses may reorder, group or repeat, with partial effects before faults; the final section commits only when the whole instruction can commit.

Pitfalls / Common Confusions

Incompatible with Zcd
CM.POP does NOT ret — only restores registers and deallocates frame
Register list and stack adjustment constrained by encoding

FAQ

Can stack_adj be any multiple of 16?

No. The register list and XLEN determine base; only base, base+16, base+32, and base+48 are encodable.

Are accesses before a fault guaranteed to have no effect?

No. Some destination registers may already be loaded. The sequence re-executes after the trap handler; the loads are not collectively atomic.