feat(mir): 增加 Lab3 AArch64 MVP 后端与 --emit-asm 支持
This commit is contained in:
@@ -1,4 +1,75 @@
|
||||
// 汇编打印:
|
||||
// - 将最终机器指令(MIR)打印为 ARMv8-A / AArch64 汇编(.s)
|
||||
// - 负责标签、伪指令、段信息等输出(按需要实现)
|
||||
#include "mir/MIR.h"
|
||||
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace mir {
|
||||
namespace {
|
||||
|
||||
const FrameSlot& GetFrameSlot(const MachineFunction& function,
|
||||
const Operand& operand) {
|
||||
if (operand.kind() != Operand::Kind::FrameIndex) {
|
||||
throw std::runtime_error("期望 FrameIndex 操作数");
|
||||
}
|
||||
return function.frame_slot(operand.frame_index());
|
||||
}
|
||||
|
||||
void PrintStackAccess(std::ostream& os, const char* mnemonic, PhysReg reg,
|
||||
int offset) {
|
||||
os << " " << mnemonic << " " << PhysRegName(reg) << ", [x29, #" << offset
|
||||
<< "]\n";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void PrintAsm(const MachineFunction& function, std::ostream& os) {
|
||||
os << ".text\n";
|
||||
os << ".global " << function.name() << "\n";
|
||||
os << ".type " << function.name() << ", %function\n";
|
||||
os << function.name() << ":\n";
|
||||
|
||||
for (const auto& inst : function.entry().instructions()) {
|
||||
const auto& ops = inst.operands();
|
||||
switch (inst.opcode()) {
|
||||
case Opcode::Prologue:
|
||||
os << " stp x29, x30, [sp, #-16]!\n";
|
||||
os << " mov x29, sp\n";
|
||||
if (function.frame_size() > 0) {
|
||||
os << " sub sp, sp, #" << function.frame_size() << "\n";
|
||||
}
|
||||
break;
|
||||
case Opcode::Epilogue:
|
||||
if (function.frame_size() > 0) {
|
||||
os << " add sp, sp, #" << function.frame_size() << "\n";
|
||||
}
|
||||
os << " ldp x29, x30, [sp], #16\n";
|
||||
break;
|
||||
case Opcode::MovImm:
|
||||
os << " mov " << PhysRegName(ops.at(0).reg()) << ", #"
|
||||
<< ops.at(1).imm() << "\n";
|
||||
break;
|
||||
case Opcode::LoadStack: {
|
||||
const auto& slot = GetFrameSlot(function, ops.at(1));
|
||||
PrintStackAccess(os, "ldur", ops.at(0).reg(), slot.offset);
|
||||
break;
|
||||
}
|
||||
case Opcode::StoreStack: {
|
||||
const auto& slot = GetFrameSlot(function, ops.at(1));
|
||||
PrintStackAccess(os, "stur", ops.at(0).reg(), slot.offset);
|
||||
break;
|
||||
}
|
||||
case Opcode::AddRR:
|
||||
os << " add " << PhysRegName(ops.at(0).reg()) << ", "
|
||||
<< PhysRegName(ops.at(1).reg()) << ", "
|
||||
<< PhysRegName(ops.at(2).reg()) << "\n";
|
||||
break;
|
||||
case Opcode::Ret:
|
||||
os << " ret\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
os << ".size " << function.name() << ", .-" << function.name() << "\n";
|
||||
}
|
||||
|
||||
} // namespace mir
|
||||
|
||||
Reference in New Issue
Block a user