|
|
|
|
@ -422,6 +422,18 @@ namespace mir
|
|
|
|
|
case Opcode::Prologue:
|
|
|
|
|
{
|
|
|
|
|
const auto &cs_regs = function.GetCalleeSavedRegs();
|
|
|
|
|
// 若函数无需帧(leaf + 无栈槽 + 无被调用者保存寄存器),跳过帧设置
|
|
|
|
|
bool has_frame = function.GetFrameSize() > 0 || !cs_regs.empty();
|
|
|
|
|
if (!has_frame) {
|
|
|
|
|
// 检查是否有 Call 指令,若有则需要保存 LR
|
|
|
|
|
for (const auto &blk : function.GetBlocks()) {
|
|
|
|
|
for (const auto &i : blk->GetInstructions()) {
|
|
|
|
|
if (i.GetOpcode() == Opcode::Call) { has_frame = true; break; }
|
|
|
|
|
}
|
|
|
|
|
if (has_frame) break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!has_frame) return; // leaf 函数,无需帧
|
|
|
|
|
os << " stp x29, x30, [sp, #-16]!\n";
|
|
|
|
|
os << " mov x29, sp\n";
|
|
|
|
|
if (function.GetFrameSize() > 0)
|
|
|
|
|
@ -448,6 +460,16 @@ namespace mir
|
|
|
|
|
case Opcode::Epilogue:
|
|
|
|
|
{
|
|
|
|
|
const auto &cs_regs = function.GetCalleeSavedRegs();
|
|
|
|
|
bool has_frame = function.GetFrameSize() > 0 || !cs_regs.empty();
|
|
|
|
|
if (!has_frame) {
|
|
|
|
|
for (const auto &blk : function.GetBlocks()) {
|
|
|
|
|
for (const auto &i : blk->GetInstructions()) {
|
|
|
|
|
if (i.GetOpcode() == Opcode::Call) { has_frame = true; break; }
|
|
|
|
|
}
|
|
|
|
|
if (has_frame) break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!has_frame) { os << " ret\n"; return; }
|
|
|
|
|
int cs_offset = 0;
|
|
|
|
|
for (auto r : cs_regs)
|
|
|
|
|
{
|
|
|
|
|
|