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.
Restore registers, deallocate frame, and ret
CM.POPRET (Zcmp) pops registers in {reg_list}, adjusts sp, then executes ret. It does not write a0. It reuses c.fsdsp encoding and is therefore incompatible with Zcd. After the loads complete, the final atomic section commits the sp adjustment and ret. It is part of Zcmp and depends on Zca.
Shows only Zcmp architectural sequences and conditions; access order, grouping, or replay does not imply implementation detail.
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.
Load the listed registers from the stack, then add stack_adj to sp. Return through restored ra, leaving a0 unchanged.
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.
No. The register list and XLEN determine base; only base, base+16, base+32, and base+48 are encodable.
No. Some destination registers may already be loaded. The sequence re-executes after the trap handler; the loads are not collectively atomic.