|
|
|
|
@ -7,6 +7,8 @@
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
#include "utils/Log.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 引用全局变量(定义在 Lowering.cpp 中)
|
|
|
|
|
extern std::vector<mir::GlobalVarInfo> g_globalVars;
|
|
|
|
|
|
|
|
|
|
@ -21,6 +23,46 @@ const FrameSlot& GetFrameSlot(const MachineFunction& function,
|
|
|
|
|
return function.GetFrameSlot(operand.GetFrameIndex());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitStackLoad(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " lw " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t4, " << offset << "\n";
|
|
|
|
|
os << " add t4, " << PhysRegName(base) << ", t4\n";
|
|
|
|
|
os << " lw " << PhysRegName(dst) << ", 0(t4)\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitStackStore(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " sw " << PhysRegName(src) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t4, " << offset << "\n";
|
|
|
|
|
os << " add t4, " << PhysRegName(base) << ", t4\n";
|
|
|
|
|
os << " sw " << PhysRegName(src) << ", 0(t4)\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitStackLoadFloat(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " flw " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t4, " << offset << "\n";
|
|
|
|
|
os << " add t4, " << PhysRegName(base) << ", t4\n";
|
|
|
|
|
os << " flw " << PhysRegName(dst) << ", 0(t4)\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitStackStoreFloat(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " fsw " << PhysRegName(src) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t4, " << offset << "\n";
|
|
|
|
|
os << " add t4, " << PhysRegName(base) << ", t4\n";
|
|
|
|
|
os << " fsw " << PhysRegName(src) << ", 0(t4)\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 输出单个函数的汇编
|
|
|
|
|
void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
// 收集所有基本块名称
|
|
|
|
|
@ -45,9 +87,34 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
|
|
|
|
|
// 在入口块的第一条指令前输出序言
|
|
|
|
|
if (!prologue_done && block.GetName() == "entry") {
|
|
|
|
|
os << " addi sp, sp, -" << total_frame_size << "\n";
|
|
|
|
|
os << " sw ra, " << (total_frame_size - 8) << "(sp)\n";
|
|
|
|
|
os << " sw s0, " << (total_frame_size - 16) << "(sp)\n";
|
|
|
|
|
// 处理大栈帧的情况
|
|
|
|
|
if (total_frame_size <= 2047) {
|
|
|
|
|
os << " addi sp, sp, -" << total_frame_size << "\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t4, -" << total_frame_size << "\n";
|
|
|
|
|
os << " add sp, sp, t4\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存 ra 和 s0
|
|
|
|
|
int ra_offset = total_frame_size - 8;
|
|
|
|
|
int s0_offset = total_frame_size - 16;
|
|
|
|
|
|
|
|
|
|
if (ra_offset <= 2047) {
|
|
|
|
|
os << " sw ra, " << ra_offset << "(sp)\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t4, " << ra_offset << "\n";
|
|
|
|
|
os << " add t4, sp, t4\n";
|
|
|
|
|
os << " sw ra, 0(t4)\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s0_offset <= 2047) {
|
|
|
|
|
os << " sw s0, " << s0_offset << "(sp)\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t4, " << s0_offset << "\n";
|
|
|
|
|
os << " add t4, sp, t4\n";
|
|
|
|
|
os << " sw s0, 0(t4)\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
prologue_done = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -64,12 +131,11 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
case Opcode::Load: {
|
|
|
|
|
if (ops.size() == 2 && ops.at(1).GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
os << " lw " << PhysRegName(ops.at(0).GetReg()) << ", 0("
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
int frame_idx = ops.at(1).GetFrameIndex();
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
os << " lw " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< slot.offset << "(sp)\n";
|
|
|
|
|
EmitStackLoad(os, ops.at(0).GetReg(), slot.offset);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@ -77,15 +143,14 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
case Opcode::Store: {
|
|
|
|
|
if (ops.size() == 2 && ops.at(1).GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
os << " sw " << PhysRegName(ops.at(0).GetReg()) << ", 0("
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
int frame_idx = ops.at(1).GetFrameIndex();
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
os << " sw " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< slot.offset << "(sp)\n";
|
|
|
|
|
EmitStackStore(os, ops.at(0).GetReg(), slot.offset);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case Opcode::Add:
|
|
|
|
|
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
@ -142,6 +207,12 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Opcode::Sltiu: // <-- 添加这个
|
|
|
|
|
os << " sltiu " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< ops.at(2).GetImm() << "\n";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Opcode::Xori:
|
|
|
|
|
os << " xori " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
@ -161,8 +232,8 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
|
|
|
|
|
case Opcode::StoreGlobal: {
|
|
|
|
|
std::string global_name = ops.at(1).GetGlobalName();
|
|
|
|
|
os << " la t0, " << global_name << "\n";
|
|
|
|
|
os << " sw " << PhysRegName(ops.at(0).GetReg()) << ", 0(t0)\n";
|
|
|
|
|
os << " la t1, " << global_name << "\n";
|
|
|
|
|
os << " sw " << PhysRegName(ops.at(0).GetReg()) << ", 0(t1)\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -186,8 +257,13 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
case Opcode::LoadAddr: {
|
|
|
|
|
int frame_idx = ops.at(1).GetFrameIndex();
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
os << " addi " << PhysRegName(ops.at(0).GetReg()) << ", sp, "
|
|
|
|
|
<< slot.offset << "\n";
|
|
|
|
|
if (slot.offset >= -2048 && slot.offset <= 2047) {
|
|
|
|
|
os << " addi " << PhysRegName(ops.at(0).GetReg()) << ", sp, " << slot.offset << "\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li " << PhysRegName(ops.at(0).GetReg()) << ", " << slot.offset << "\n";
|
|
|
|
|
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", sp, "
|
|
|
|
|
<< PhysRegName(ops.at(0).GetReg()) << "\n";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -202,12 +278,38 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Opcode::Ret:
|
|
|
|
|
os << " lw ra, " << (total_frame_size - 8) << "(sp)\n";
|
|
|
|
|
os << " lw s0, " << (total_frame_size - 16) << "(sp)\n";
|
|
|
|
|
os << " addi sp, sp, " << total_frame_size << "\n";
|
|
|
|
|
case Opcode::Ret:{
|
|
|
|
|
// 恢复 ra 和 s0
|
|
|
|
|
int ra_offset = total_frame_size - 8;
|
|
|
|
|
int s0_offset = total_frame_size - 16;
|
|
|
|
|
|
|
|
|
|
if (ra_offset <= 2047) {
|
|
|
|
|
os << " lw ra, " << ra_offset << "(sp)\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t3, " << ra_offset << "\n";
|
|
|
|
|
os << " add t3, sp, t3\n";
|
|
|
|
|
os << " lw ra, 0(t3)\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s0_offset <= 2047) {
|
|
|
|
|
os << " lw s0, " << s0_offset << "(sp)\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t3, " << s0_offset << "\n";
|
|
|
|
|
os << " add t3, sp, t3\n";
|
|
|
|
|
os << " lw s0, 0(t3)\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 恢复 sp
|
|
|
|
|
if (total_frame_size <= 2047) {
|
|
|
|
|
os << " addi sp, sp, " << total_frame_size << "\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t3, " << total_frame_size << "\n";
|
|
|
|
|
os << " add sp, sp, t3\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
os << " ret\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case Opcode::Br: {
|
|
|
|
|
auto* target = reinterpret_cast<MachineBasicBlock*>(ops[0].GetImm64());
|
|
|
|
|
@ -300,24 +402,22 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
case Opcode::LoadFloat:
|
|
|
|
|
if (ops.size() == 2 && ops[1].GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
os << " flw " << PhysRegName(ops[0].GetReg()) << ", 0("
|
|
|
|
|
<< PhysRegName(ops[1].GetReg()) << ")\n";
|
|
|
|
|
<< PhysRegName(ops[1].GetReg()) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
int frame_idx = ops[1].GetFrameIndex();
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
os << " flw " << PhysRegName(ops[0].GetReg()) << ", "
|
|
|
|
|
<< slot.offset << "(sp)\n";
|
|
|
|
|
EmitStackLoadFloat(os, ops[0].GetReg(), slot.offset);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Opcode::StoreFloat:
|
|
|
|
|
if (ops.size() == 2 && ops[1].GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
os << " fsw " << PhysRegName(ops[0].GetReg()) << ", 0("
|
|
|
|
|
<< PhysRegName(ops[1].GetReg()) << ")\n";
|
|
|
|
|
<< PhysRegName(ops[1].GetReg()) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
int frame_idx = ops[1].GetFrameIndex();
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
os << " fsw " << PhysRegName(ops[0].GetReg()) << ", "
|
|
|
|
|
<< slot.offset << "(sp)\n";
|
|
|
|
|
EmitStackStoreFloat(os, ops[0].GetReg(), slot.offset);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|