|
|
|
|
@ -24,7 +24,7 @@ const FrameSlot& GetFrameSlot(const MachineFunction& function,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 32位整数加载/存储
|
|
|
|
|
void EmitStackLoad(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
void EmitStackLoad(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::S0) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " lw " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
@ -34,7 +34,7 @@ void EmitStackLoad(std::ostream& os, PhysReg dst, int offset, PhysReg base = Phy
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitStackStore(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
void EmitStackStore(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::S0) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " sw " << PhysRegName(src) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
@ -45,7 +45,7 @@ void EmitStackStore(std::ostream& os, PhysReg src, int offset, PhysReg base = Ph
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 64位指针加载/存储
|
|
|
|
|
void EmitStackLoad64(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
void EmitStackLoad64(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::S0) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " ld " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
@ -55,7 +55,7 @@ void EmitStackLoad64(std::ostream& os, PhysReg dst, int offset, PhysReg base = P
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitStackStore64(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
void EmitStackStore64(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::S0) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " sd " << PhysRegName(src) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
@ -66,7 +66,7 @@ void EmitStackStore64(std::ostream& os, PhysReg src, int offset, PhysReg base =
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 浮点加载/存储(保持32位)
|
|
|
|
|
void EmitStackLoadFloat(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
void EmitStackLoadFloat(std::ostream& os, PhysReg dst, int offset, PhysReg base = PhysReg::S0) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " flw " << PhysRegName(dst) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
@ -76,7 +76,7 @@ void EmitStackLoadFloat(std::ostream& os, PhysReg dst, int offset, PhysReg base
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EmitStackStoreFloat(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::SP) {
|
|
|
|
|
void EmitStackStoreFloat(std::ostream& os, PhysReg src, int offset, PhysReg base = PhysReg::S0) {
|
|
|
|
|
if (offset >= -2048 && offset <= 2047) {
|
|
|
|
|
os << " fsw " << PhysRegName(src) << ", " << offset << "(" << PhysRegName(base) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
@ -95,7 +95,8 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int frame_size = function.GetFrameSize(); // 局部变量区大小(正数)
|
|
|
|
|
int total_frame_size = frame_size + 16; // +16 用于保存 ra(8) 和 s0(8)
|
|
|
|
|
int local_vars = function.GetLocalVarsSize();
|
|
|
|
|
int total_frame = local_vars + 16 ;
|
|
|
|
|
bool prologue_done = false;
|
|
|
|
|
|
|
|
|
|
for (const auto& block_ptr : function.GetBlocks()) {
|
|
|
|
|
@ -111,19 +112,19 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
|
|
|
|
|
// 在入口块的第一条指令前输出序言
|
|
|
|
|
if (!prologue_done && block.GetName() == "entry") {
|
|
|
|
|
// 分配栈帧:sp -= total_frame_size
|
|
|
|
|
if (total_frame_size <= 2047) {
|
|
|
|
|
os << " addi sp, sp, -" << total_frame_size << "\n";
|
|
|
|
|
// 分配栈帧:sp -= total_frame
|
|
|
|
|
if (total_frame <= 2047) {
|
|
|
|
|
os << " addi sp, sp, -" << total_frame << "\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t4, -" << total_frame_size << "\n";
|
|
|
|
|
os << " li t4, -" << total_frame << "\n";
|
|
|
|
|
os << " add sp, sp, t4\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存 ra 和 s0(在局部变量区之后,即 sp + frame_size 处)
|
|
|
|
|
// ra 保存在 sp + frame_size
|
|
|
|
|
// s0 保存在 sp + frame_size + 8
|
|
|
|
|
int ra_offset = frame_size;
|
|
|
|
|
int s0_offset = frame_size + 8;
|
|
|
|
|
int ra_offset = local_vars;
|
|
|
|
|
int s0_offset = local_vars + 8;
|
|
|
|
|
|
|
|
|
|
if (ra_offset <= 2047) {
|
|
|
|
|
os << " sd ra, " << ra_offset << "(sp)\n";
|
|
|
|
|
@ -140,7 +141,7 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
os << " add t4, sp, t4\n";
|
|
|
|
|
os << " sd s0, 0(t4)\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
os << " mv s0, sp\n";
|
|
|
|
|
prologue_done = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -155,47 +156,77 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Opcode::Load: {
|
|
|
|
|
if (ops.size() == 2 && ops.at(1).GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
// 寄存器间接寻址 - 使用 ld(64位)
|
|
|
|
|
os << " ld " << PhysRegName(ops.at(0).GetReg()) << ", 0("
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
int frame_idx = ops.at(1).GetFrameIndex();
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
// 根据槽大小决定加载宽度
|
|
|
|
|
if (slot.size == 8) {
|
|
|
|
|
EmitStackLoad64(os, ops.at(0).GetReg(), slot.offset);
|
|
|
|
|
if (ops.size() == 2 && ops[1].GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
os << " ld " << PhysRegName(ops[0].GetReg()) << ", 0(" << PhysRegName(ops[1].GetReg()) << ")\n";
|
|
|
|
|
} else if (ops.size() == 2 && ops[1].GetKind() == Operand::Kind::Imm) {
|
|
|
|
|
// 用于调用者 outgoing 存储的占位偏移(将在 Outgoing 中修正)
|
|
|
|
|
int offset = ops[1].GetImm(); // 实际偏移 = local_vars + 16 + offset
|
|
|
|
|
os << " ld " << PhysRegName(ops[0].GetReg()) << ", " << offset << "(sp)\n";
|
|
|
|
|
} else {
|
|
|
|
|
EmitStackLoad(os, ops.at(0).GetReg(), slot.offset);
|
|
|
|
|
int frame_idx = ops[1].GetFrameIndex();
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
if (slot.size == 8) EmitStackLoad64(os, ops[0].GetReg(), slot.offset);
|
|
|
|
|
else EmitStackLoad(os, ops[0].GetReg(), slot.offset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case Opcode::Store: {
|
|
|
|
|
if (ops.size() == 2 && ops.at(1).GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
// 寄存器间接寻址 - 使用 sd(64位)
|
|
|
|
|
os << " sd " << PhysRegName(ops.at(0).GetReg()) << ", 0("
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ")\n";
|
|
|
|
|
} else {
|
|
|
|
|
int frame_idx = ops.at(1).GetFrameIndex();
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
// 根据槽大小决定存储宽度
|
|
|
|
|
if (slot.size == 8) {
|
|
|
|
|
EmitStackStore64(os, ops.at(0).GetReg(), slot.offset);
|
|
|
|
|
if (ops.size() == 2 && ops[1].GetKind() == Operand::Kind::Reg) {
|
|
|
|
|
os << " sd " << PhysRegName(ops[0].GetReg()) << ", 0(" << PhysRegName(ops[1].GetReg()) << ")\n";
|
|
|
|
|
} else if (ops.size() == 2 && ops[1].GetKind() == Operand::Kind::Imm) {
|
|
|
|
|
// outgoing 存储:偏移 = local_vars + 16 + ops[1].GetImm()
|
|
|
|
|
int offset = ops[1].GetImm();
|
|
|
|
|
// 实际偏移需在 AsmPrinter 中加上 local_vars+16,这里简单先直接用 offset(动态修正稍复杂)
|
|
|
|
|
// 临时方案:直接生成 sw t0, offset(sp),但 offset 应为 local_vars+16=?
|
|
|
|
|
// 由于 AsmPrinter 中可访问 function.GetLocalVarsSize(),我们计算:
|
|
|
|
|
int actual_offset = function.GetLocalVarsSize() + 16 + offset;
|
|
|
|
|
if (actual_offset <= 2047) os << " sd " << PhysRegName(ops[0].GetReg()) << ", " << actual_offset << "(sp)\n";
|
|
|
|
|
else { /* 扩展大偏移 */ }
|
|
|
|
|
} else {
|
|
|
|
|
EmitStackStore(os, ops.at(0).GetReg(), slot.offset);
|
|
|
|
|
int frame_idx = ops[1].GetFrameIndex();
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
if (slot.size == 8) EmitStackStore64(os, ops[0].GetReg(), slot.offset);
|
|
|
|
|
else EmitStackStore(os, ops[0].GetReg(), slot.offset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case Opcode::LoadCallerStackArg: {
|
|
|
|
|
// ops: [0] dst (T0), [1] dstFrameIndex, [2] argvIndex (Imm)
|
|
|
|
|
int argv_index = ops[2].GetImm();
|
|
|
|
|
int dst_slot = ops[1].GetFrameIndex();
|
|
|
|
|
int total_frame = function.GetFrameSize();
|
|
|
|
|
// 调用者栈参数位于 sp + total_frame + argv_index*8
|
|
|
|
|
int caller_offset = total_frame + argv_index * 8;
|
|
|
|
|
// 加载到 T0
|
|
|
|
|
if (caller_offset <= 2047) {
|
|
|
|
|
os << " ld " << PhysRegName(ops[0].GetReg()) << ", " << caller_offset << "(sp)\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t4, " << caller_offset << "\n";
|
|
|
|
|
os << " add t4, sp, t4\n";
|
|
|
|
|
os << " ld " << PhysRegName(ops[0].GetReg()) << ", 0(t4)\n";
|
|
|
|
|
}
|
|
|
|
|
// 再存入本地槽
|
|
|
|
|
const auto& slot = function.GetFrameSlot(dst_slot);
|
|
|
|
|
if (slot.size == 8) {
|
|
|
|
|
EmitStackStore64(os, ops[0].GetReg(), slot.offset);
|
|
|
|
|
} else {
|
|
|
|
|
EmitStackStore(os, ops[0].GetReg(), slot.offset);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case Opcode::Add:
|
|
|
|
|
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(2).GetReg()) << "\n";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Opcode::Addi:
|
|
|
|
|
os << " addi " << PhysRegName(ops[0].GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops[1].GetReg()) << ", "
|
|
|
|
|
<< ops[2].GetImm() << "\n";
|
|
|
|
|
break;
|
|
|
|
|
case Opcode::Sub:
|
|
|
|
|
os << " sub " << PhysRegName(ops.at(0).GetReg()) << ", "
|
|
|
|
|
<< PhysRegName(ops.at(1).GetReg()) << ", "
|
|
|
|
|
@ -299,10 +330,10 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
const auto& slot = function.GetFrameSlot(frame_idx);
|
|
|
|
|
// 计算地址(64 位),offset 是正数
|
|
|
|
|
if (slot.offset <= 2047) {
|
|
|
|
|
os << " addi " << PhysRegName(ops.at(0).GetReg()) << ", sp, " << slot.offset << "\n";
|
|
|
|
|
os << " addi " << PhysRegName(ops.at(0).GetReg()) << ", s0, " << slot.offset << "\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li " << PhysRegName(ops.at(0).GetReg()) << ", " << slot.offset << "\n";
|
|
|
|
|
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", sp, "
|
|
|
|
|
os << " add " << PhysRegName(ops.at(0).GetReg()) << ", s0, "
|
|
|
|
|
<< PhysRegName(ops.at(0).GetReg()) << "\n";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
@ -322,32 +353,33 @@ void PrintAsmFunction(const MachineFunction& function, std::ostream& os) {
|
|
|
|
|
|
|
|
|
|
case Opcode::Ret:{
|
|
|
|
|
// 恢复 ra 和 s0
|
|
|
|
|
int ra_offset = frame_size;
|
|
|
|
|
int s0_offset = frame_size + 8;
|
|
|
|
|
int ra_offset = local_vars;
|
|
|
|
|
int s0_offset = local_vars + 8;
|
|
|
|
|
|
|
|
|
|
if (ra_offset <= 2047) {
|
|
|
|
|
os << " ld ra, " << ra_offset << "(sp)\n";
|
|
|
|
|
os << " ld ra, " << ra_offset << "(s0)\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t3, " << ra_offset << "\n";
|
|
|
|
|
os << " add t3, sp, t3\n";
|
|
|
|
|
os << " add t3, s0, t3\n";
|
|
|
|
|
os << " ld ra, 0(t3)\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 恢复 sp
|
|
|
|
|
if (total_frame <= 2047) {
|
|
|
|
|
os << " addi sp, s0, " << total_frame << "\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t3, " << total_frame << "\n";
|
|
|
|
|
os << " add sp, s0, t3\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s0_offset <= 2047) {
|
|
|
|
|
os << " ld s0, " << s0_offset << "(sp)\n";
|
|
|
|
|
os << " ld s0, " << s0_offset << "(s0)\n";
|
|
|
|
|
} else {
|
|
|
|
|
os << " li t3, " << s0_offset << "\n";
|
|
|
|
|
os << " add t3, sp, t3\n";
|
|
|
|
|
os << " add t3, s0, t3\n";
|
|
|
|
|
os << " ld 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;
|
|
|
|
|
|