|
|
|
|
@ -5,6 +5,15 @@
|
|
|
|
|
|
|
|
|
|
#include "utils/Log.h"
|
|
|
|
|
|
|
|
|
|
#define DEBUG_Frame
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_Frame
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#define DEBUG_MSG(msg) std::cerr << "[Frame Debug] " << msg << std::endl
|
|
|
|
|
#else
|
|
|
|
|
#define DEBUG_MSG(msg)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace mir {
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
@ -14,112 +23,8 @@ int AlignTo(int value, int align) {
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
// 计算栈帧中所有栈槽的总大小
|
|
|
|
|
static int CalculateStackFrameSize(MachineFunction& function) {
|
|
|
|
|
int totalSize = 0;
|
|
|
|
|
|
|
|
|
|
// 计算所有栈槽的总大小
|
|
|
|
|
for (auto& slot : function.GetFrameSlots()) {
|
|
|
|
|
// 栈槽偏移从 -4, -8, -12 开始(负偏移)
|
|
|
|
|
int offset = -(totalSize + slot.size);
|
|
|
|
|
slot.offset = offset;
|
|
|
|
|
totalSize += slot.size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回局部变量总大小(不需要额外加 16,因为 sp 已经减了 16)
|
|
|
|
|
return totalSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 单函数版本的栈帧布局(原有逻辑扩展)
|
|
|
|
|
void RunFrameLowering(MachineFunction& function) {
|
|
|
|
|
// 计算栈帧大小
|
|
|
|
|
int frameSize = CalculateStackFrameSize(function);
|
|
|
|
|
function.SetFrameSize(frameSize);
|
|
|
|
|
|
|
|
|
|
// 获取入口基本块
|
|
|
|
|
if (function.GetBasicBlocks().empty()) {
|
|
|
|
|
throw std::runtime_error(FormatError("framelowering", "函数没有基本块"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MachineBasicBlock& entry = function.GetEntry();
|
|
|
|
|
|
|
|
|
|
// 获取指令列表
|
|
|
|
|
auto& instrs = entry.GetInstructions();
|
|
|
|
|
|
|
|
|
|
// 创建新的指令列表,先放序言,再放原有指令
|
|
|
|
|
std::vector<MachineInstr> newInstrs;
|
|
|
|
|
|
|
|
|
|
// ========== 函数序言 ==========
|
|
|
|
|
// 1. stp x29, x30, [sp, #-16]! (保存 FP 和 LR,同时 sp -= 16)
|
|
|
|
|
/* newInstrs.emplace_back(Opcode::StoreStackPair,
|
|
|
|
|
std::vector<Operand>{Operand::Reg(PhysReg::X29),
|
|
|
|
|
Operand::Reg(PhysReg::X30),
|
|
|
|
|
Operand::Imm(-16)});
|
|
|
|
|
|
|
|
|
|
// 2. mov x29, sp (设置 FP)
|
|
|
|
|
newInstrs.emplace_back(Opcode::MovReg,
|
|
|
|
|
std::vector<Operand>{Operand::Reg(PhysReg::X29),
|
|
|
|
|
Operand::Reg(PhysReg::SP)});
|
|
|
|
|
|
|
|
|
|
// 3. sub sp, sp, #frameSize (分配局部变量空间)
|
|
|
|
|
if (frameSize > 0) {
|
|
|
|
|
int alignedSize = (frameSize + 15) & ~15; // 16 字节对齐
|
|
|
|
|
newInstrs.emplace_back(Opcode::SubRI,
|
|
|
|
|
std::vector<Operand>{Operand::Reg(PhysReg::SP),
|
|
|
|
|
Operand::Reg(PhysReg::SP),
|
|
|
|
|
Operand::Imm(alignedSize)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制原有指令
|
|
|
|
|
for (auto& instr : instrs) {
|
|
|
|
|
newInstrs.push_back(std::move(instr));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 替换指令列表
|
|
|
|
|
instrs = std::move(newInstrs); */
|
|
|
|
|
|
|
|
|
|
// ========== 处理尾声 ==========
|
|
|
|
|
/* for (auto& bb : function.GetBasicBlocks()) {
|
|
|
|
|
auto& instructions = bb->GetInstructions();
|
|
|
|
|
|
|
|
|
|
// 查找 Ret 指令
|
|
|
|
|
for (auto it = instructions.begin(); it != instructions.end(); ++it) {
|
|
|
|
|
if (it->GetOpcode() == Opcode::Ret) {
|
|
|
|
|
// 创建尾声指令
|
|
|
|
|
std::vector<MachineInstr> epilogue;
|
|
|
|
|
|
|
|
|
|
// 1. add sp, sp, #frameSize (释放局部变量空间)
|
|
|
|
|
if (frameSize > 0) {
|
|
|
|
|
int alignedSize = (frameSize + 15) & ~15;
|
|
|
|
|
epilogue.emplace_back(Opcode::AddRI,
|
|
|
|
|
std::vector<Operand>{Operand::Reg(PhysReg::SP),
|
|
|
|
|
Operand::Reg(PhysReg::SP),
|
|
|
|
|
Operand::Imm(alignedSize)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. ldp x29, x30, [sp], #16 (恢复 FP 和 LR,同时 sp += 16)
|
|
|
|
|
epilogue.emplace_back(Opcode::LoadStackPair,
|
|
|
|
|
std::vector<Operand>{Operand::Reg(PhysReg::X29),
|
|
|
|
|
Operand::Reg(PhysReg::X30),
|
|
|
|
|
Operand::Imm(16)});
|
|
|
|
|
|
|
|
|
|
// 在 Ret 指令前插入尾声
|
|
|
|
|
instructions.insert(it, epilogue.begin(), epilogue.end());
|
|
|
|
|
break; // 每个函数只处理第一个 Ret(实际应该处理所有)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 模块版本的栈帧布局
|
|
|
|
|
void RunFrameLowering(MachineModule& module) {
|
|
|
|
|
// 对模块中的每个函数执行栈帧布局
|
|
|
|
|
for (auto& func : module.GetFunctions()) {
|
|
|
|
|
RunFrameLowering(*func);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* void RunFrameLowering(MachineFunction& function) {
|
|
|
|
|
DEBUG_MSG("function RunFrameLowering");
|
|
|
|
|
int cursor = 0;
|
|
|
|
|
for (const auto& slot : function.GetFrameSlots()) {
|
|
|
|
|
cursor += slot.size;
|
|
|
|
|
@ -135,16 +40,36 @@ void RunFrameLowering(MachineModule& module) {
|
|
|
|
|
}
|
|
|
|
|
function.SetFrameSize(AlignTo(cursor, 16));
|
|
|
|
|
|
|
|
|
|
auto& insts = function.GetEntry().GetInstructions();
|
|
|
|
|
std::vector<MachineInstr> lowered;
|
|
|
|
|
lowered.emplace_back(Opcode::Prologue);
|
|
|
|
|
for (const auto& inst : insts) {
|
|
|
|
|
if (inst.GetOpcode() == Opcode::Ret) {
|
|
|
|
|
lowered.emplace_back(Opcode::Epilogue);
|
|
|
|
|
// 基本块
|
|
|
|
|
const auto& blocks = function.GetBasicBlocks();
|
|
|
|
|
|
|
|
|
|
for (const auto& bb : blocks) {
|
|
|
|
|
DEBUG_MSG("block");
|
|
|
|
|
auto& insts = bb->GetInstructions();
|
|
|
|
|
std::vector<MachineInstr> lowered;
|
|
|
|
|
DEBUG_MSG("empalace Prologue");
|
|
|
|
|
lowered.emplace_back(Opcode::Prologue);
|
|
|
|
|
// 输出基本块中的指令
|
|
|
|
|
for (const auto& inst : insts) {
|
|
|
|
|
DEBUG_MSG("inst");
|
|
|
|
|
if (inst.GetOpcode() == Opcode::Ret) {
|
|
|
|
|
DEBUG_MSG("empalace Epilogue");
|
|
|
|
|
lowered.emplace_back(Opcode::Epilogue);
|
|
|
|
|
}
|
|
|
|
|
lowered.push_back(inst);
|
|
|
|
|
}
|
|
|
|
|
lowered.push_back(inst);
|
|
|
|
|
insts = std::move(lowered);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 模块版本的栈帧布局
|
|
|
|
|
void RunFrameLowering(MachineModule& module) {
|
|
|
|
|
// 对模块中的每个函数执行栈帧布局
|
|
|
|
|
DEBUG_MSG("module RunFrameLowering");
|
|
|
|
|
for (auto& func : module.GetFunctions()) {
|
|
|
|
|
RunFrameLowering(*func);
|
|
|
|
|
}
|
|
|
|
|
insts = std::move(lowered);
|
|
|
|
|
} */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace mir
|
|
|
|
|
|
|
|
|
|
|