Home/Instructions/CM-POPRETZ
CM.POPRETZ

RISC-V CM.POPRETZ Instruction Details

Instruction ManualC2 (Zcmp CMPP)

Restore registers, a0=0, deallocate frame, and ret

Instruction Syntax

cm.popretz {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.
The final section zeros a0, adjusts sp and executes ret, clearing bit 0 of restored ra without writing a new link.
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.POPRETZ (Zcmp) pops registers in {reg_list}, sets a0 to zero, adjusts sp, then ret. Used for function epilogues returning zero. Differs from POPRET by explicitly zeroing a0. Reuses c.fsdsp encoding. Part of Zcmp, depends on Zca.

CM.POPRETZ Decode & Execute Animation

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

cm.popretz {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; a0 <- 0; sp <- 0x00001040; PC <- restored ra & ~1 = 0x00002000
16-bit encoding fields
15..13
funct3
101
12..8
fixed
11100
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; target = 0x00002001 & ~1 = 0x00002000.
s2/x18 <- mem32[0x0000103C]=0x00000030; s1/x9 <- mem32[0x00001038]=0x00000020; s0/x8 <- mem32[0x00001034]=0x00000010; ra/x1 <- mem32[0x00001030]=0x00002001; a0 <- 0; sp <- 0x00001040; PC <- restored ra & ~1 = 0x00002000
Architectural state has not been committed.

Quick Understanding & Search Notes

Load the listed registers from the stack, then add stack_adj to sp. Set a0 to zero and return through restored ra.

RV32/RV64 Zcmp requires Zca and conflicts with Zcd. 16-bit CMPP: bits[15:13]=101, [12:8]=11100, 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, a0=0, and ret 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.
  • The final section zeros a0, adjusts sp and executes ret, clearing bit 0 of restored ra without writing a new link.
  • 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

Overwrites a0 with zero (destroys any computed return value)
Incompatible with Zcd

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.