栈调整可以是任意 16 的倍数吗?
不可以。先按寄存器列表与 XLEN 计算 base,只允许 base、base+16、base+32、base+48。
恢复寄存器、回收栈帧并执行ret
CM.POPRET (Zcmp)弹出{reg_list}中的寄存器,调整sp,然后执行ret。它不写a0;复用c.fsdsp编码,因此与Zcd不兼容。加载完成后,sp调整和ret在最终原子段提交。属于Zcmp,依赖Zca。
仅展示 Zcmp 架构可见序列和条件;访问次序、合并或重试不代表实现细节。
Zcmp 依赖 Zca 且与 Zcd 不兼容。正确执行要求 sp 指向幂等内存;RV32E 仅允许 rlist=4-6。输入值为保存前寄存器值或成功加载的内存值;complete 假设 EEI 允许全部访问,不代表任意地址都会成功。
从栈加载列表寄存器,再令 sp 加上 stack_adj。随后用恢复后的 ra 返回;不改 a0。
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。
不是。部分目的寄存器可能已被加载;返回陷阱后会重新执行序列,不能把加载全部当作原子操作。