栈调整可以是任意 16 的倍数吗?
不可以。先按寄存器列表与 XLEN 计算 base,只允许 base、base+16、base+32、base+48。
恢复寄存器、a0=0、回收栈帧并返回
CM.POPRETZ (Zcmp)弹出{reg_list}中的寄存器,将a0置零,调整sp,然后执行ret。用于返回零值的函数尾声。与POPRET的区别是显式将a0清零。复用c.fsdsp编码。属于Zcmp,依赖Zca。
仅展示 Zcmp 架构可见序列和条件;访问次序、合并或重试不代表实现细节。
Zcmp 依赖 Zca 且与 Zcd 不兼容。正确执行要求 sp 指向幂等内存;RV32E 仅允许 rlist=4-6。输入值为保存前寄存器值或成功加载的内存值;complete 假设 EEI 允许全部访问,不代表任意地址都会成功。
从栈加载列表寄存器,再令 sp 加上 stack_adj。随后将 a0 置零,并用恢复后的 ra 返回。
RV32I Zcmp、访问成功:{ra,s0-s2} 共 16 字节,stack_adj=64 可编码为 rlist=7、spimm=3。PUSH 将旧 sp 下的值保存后 sp-=64;POP 类从旧 sp+48 至旧 sp+60 恢复后 sp+=64;返回形式使用恢复后的 ra,POPRETZ 另将 a0 置零。
不可以。先按寄存器列表与 XLEN 计算 base,只允许 base、base+16、base+32、base+48。
不是。部分目的寄存器可能已被加载;返回陷阱后会重新执行序列,不能把加载全部当作原子操作。