feat(mir)实现多条指令访问栈帧

feature/mir
mxr 2 days ago
parent 4f00d05c86
commit 4132f0b5ca

@ -25,12 +25,59 @@ const FrameSlot& GetFrameSlot(const MachineFunction& function,
return function.GetFrameSlot(operand.GetFrameIndex());
}
void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
/*void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
int offset) {
//os << " " << mnemonic << " " << PhysRegName(reg) << ", [x29, #" << offset
// << "]\n";
// 使用 sp 相对寻址
os << " " << mnemonic << " " << PhysRegName(reg) << ", [sp, #" << offset << "]\n";
}*/
void PrintStackAccess(std::ostream& os, const char* insn, PhysReg reg, int64_t offset) {
// 合法范围:-256 到 255
if (offset >= -256 && offset <= 255) {
os << " " << insn << " " << PhysRegName(reg) << ", [sp, #" << offset << "]\n";
return;
}
// 大偏移:使用 x16 计算地址
os << " mov x16, sp"<< "\n";
// 处理正偏移
if (offset >= 0) {
// AArch64 add immediate 范围 0~4095超过则需要分解
if (offset <= 4095) {
os << " add x16, x16, #" << offset << "\n";
} else {
// 简单分解:高部分必须是 4096 的倍数?这里为了通用,分两次加
// 更严谨的做法是循环,但栈帧一般不超过 8192两次足够
int64_t low = offset & 0xFFF; // 低12位
int64_t high = offset - low;
if (high > 0) {
os << " add x16, x16, #" << high << "\n";
}
if (low > 0) {
os << " add x16, x16, #" << low << "\n";
}
}
}
// 处理负偏移
else {
int64_t abs_offset = -offset;
if (abs_offset <= 4095) {
os << " sub x16, x16, #" << abs_offset << "\n";
} else {
int64_t low = abs_offset & 0xFFF;
int64_t high = abs_offset - low;
if (high > 0) {
os << " sub x16, x16, #" << high << "\n";
}
if (low > 0) {
os << " sub x16, x16, #" << low << "\n";
}
}
}
// 最后使用无偏移的 ldr/str注意不是 ldur/stur
os << " " << insn << " " << PhysRegName(reg) << ", [x16]\n";
}
// 打印单个操作数

@ -31,9 +31,9 @@ void RunFrameLowering(MachineFunction& function) {
// 使用正偏移,从 sp 开始
function.GetFrameSlot(slot.index).offset = cursor;
cursor += slot.size;
if (-cursor < -256) {
/*if (-cursor < -256) {
throw std::runtime_error(FormatError("mir", "暂不支持过大的栈帧"));
}
}*/
}
cursor = 0;
for (const auto& slot : function.GetFrameSlots()) {

Loading…
Cancel
Save