forked from NUDT-compiler/nudt-compiler-cpp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.4 KiB
79 lines
2.4 KiB
#include "mir/MIR.h"
|
|
|
|
#include <ostream>
|
|
#include <stdexcept>
|
|
|
|
#include "utils/Log.h"
|
|
|
|
namespace mir {
|
|
namespace {
|
|
|
|
const FrameSlot& GetFrameSlot(const MachineFunction& function,
|
|
const Operand& operand) {
|
|
if (operand.GetKind() != Operand::Kind::FrameIndex) {
|
|
throw std::runtime_error(FormatError("mir", "期望 FrameIndex 操作数"));
|
|
}
|
|
return function.GetFrameSlot(operand.GetFrameIndex());
|
|
}
|
|
|
|
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.GetName() << "\n";
|
|
os << ".type " << function.GetName() << ", %function\n";
|
|
os << function.GetName() << ":\n";
|
|
|
|
for (const auto& inst : function.GetEntry().GetInstructions()) {
|
|
const auto& ops = inst.GetOperands();
|
|
switch (inst.GetOpcode()) {
|
|
case Opcode::Prologue:
|
|
os << " stp x29, x30, [sp, #-16]!\n";
|
|
os << " mov x29, sp\n";
|
|
if (function.GetFrameSize() > 0) {
|
|
os << " sub sp, sp, #" << function.GetFrameSize() << "\n";
|
|
}
|
|
break;
|
|
case Opcode::Epilogue:
|
|
if (function.GetFrameSize() > 0) {
|
|
os << " add sp, sp, #" << function.GetFrameSize() << "\n";
|
|
}
|
|
os << " ldp x29, x30, [sp], #16\n";
|
|
break;
|
|
case Opcode::MovImm:
|
|
os << " mov " << PhysRegName(ops.at(0).GetReg()) << ", #"
|
|
<< ops.at(1).GetImm() << "\n";
|
|
break;
|
|
case Opcode::LoadStack: {
|
|
const auto& slot = GetFrameSlot(function, ops.at(1));
|
|
PrintStackAccess(os, "ldur", ops.at(0).GetReg(), slot.offset);
|
|
break;
|
|
}
|
|
case Opcode::StoreStack: {
|
|
const auto& slot = GetFrameSlot(function, ops.at(1));
|
|
PrintStackAccess(os, "stur", ops.at(0).GetReg(), slot.offset);
|
|
break;
|
|
}
|
|
case Opcode::AddRR:
|
|
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
break;
|
|
case Opcode::Ret:
|
|
os << " ret\n";
|
|
break;
|
|
}
|
|
}
|
|
|
|
os << ".size " << function.GetName() << ", .-" << function.GetName()
|
|
<< "\n";
|
|
}
|
|
|
|
} // namespace mir
|