[backend] incorrect asm output

This commit is contained in:
ladev789
2025-06-22 20:00:03 +08:00
parent 4711fb603b
commit 88a561177d
4 changed files with 182 additions and 70 deletions

View File

@@ -13,6 +13,7 @@ const std::vector<RISCv32CodeGen::PhysicalReg> RISCv32CodeGen::allocable_regs =
std::string RISCv32CodeGen::reg_to_string(PhysicalReg reg) { std::string RISCv32CodeGen::reg_to_string(PhysicalReg reg) {
switch (reg) { switch (reg) {
case PhysicalReg::S0: return "s0";
case PhysicalReg::T0: return "t0"; case PhysicalReg::T1: return "t1"; case PhysicalReg::T0: return "t0"; case PhysicalReg::T1: return "t1";
case PhysicalReg::T2: return "t2"; case PhysicalReg::T3: return "t3"; case PhysicalReg::T2: return "t2"; case PhysicalReg::T3: return "t3";
case PhysicalReg::T4: return "t4"; case PhysicalReg::T5: return "t5"; case PhysicalReg::T4: return "t4"; case PhysicalReg::T5: return "t5";
@@ -27,7 +28,6 @@ std::string RISCv32CodeGen::reg_to_string(PhysicalReg reg) {
std::string RISCv32CodeGen::code_gen() { std::string RISCv32CodeGen::code_gen() {
std::stringstream ss; std::stringstream ss;
ss << ".text\n";
ss << module_gen(); ss << module_gen();
return ss.str(); return ss.str();
} }
@@ -35,16 +35,36 @@ std::string RISCv32CodeGen::code_gen() {
std::string RISCv32CodeGen::module_gen() { std::string RISCv32CodeGen::module_gen() {
std::stringstream ss; std::stringstream ss;
// 生成全局变量(数据段) // 生成全局变量(数据段)
for (const auto& global : module->getGlobals()) { bool has_globals = !module->getGlobals().empty();
if (has_globals) {
ss << ".data\n"; ss << ".data\n";
ss << ".globl " << global->getName() << "\n"; for (const auto& global : module->getGlobals()) {
ss << global->getName() << ":\n"; ss << ".globl " << global->getName() << "\n";
ss << " .word 0\n"; // 假设初始化为0 ss << global->getName() << ":\n";
const auto& init_values = global->getInitValues();
for (size_t i = 0; i < init_values.getValues().size(); ++i) {
auto val = init_values.getValues()[i];
auto count = init_values.getNumbers()[i];
if (auto constant = dynamic_cast<ConstantValue*>(val)) {
for (unsigned j = 0; j < count; ++j) {
if (constant->isInt()) {
ss << " .word " << constant->getInt() << "\n";
} else {
float f = constant->getFloat();
uint32_t float_bits = *(uint32_t*)&f;
ss << " .word " << float_bits << "\n";
}
}
}
}
}
} }
// 生成函数(文本段) // 生成函数(文本段)
ss << ".text\n"; if (!module->getFunctions().empty()) {
for (const auto& func : module->getFunctions()) { ss << ".text\n";
ss << function_gen(func.second.get()); for (const auto& func : module->getFunctions()) {
ss << function_gen(func.second.get());
}
} }
return ss.str(); return ss.str();
} }
@@ -54,19 +74,22 @@ std::string RISCv32CodeGen::function_gen(Function* func) {
// 函数标签 // 函数标签
ss << ".globl " << func->getName() << "\n"; ss << ".globl " << func->getName() << "\n";
ss << func->getName() << ":\n"; ss << func->getName() << ":\n";
// 序言:保存 ra分配堆栈
bool is_leaf = true; // 简化假设
ss << " addi sp, sp, -16\n";
ss << " sw ra, 12(sp)\n";
// 寄存器分配 // 寄存器分配
auto alloc = register_allocation(func); auto alloc = register_allocation(func);
// 序言:分配堆栈,保存 ra 和 s0设置帧指针
int stack_size = alloc.stack_size;
ss << " addi sp, sp, -" << stack_size << "\n";
ss << " sw ra, " << (stack_size - 4) << "(sp)\n";
ss << " sw s0, " << (stack_size - 8) << "(sp)\n";
ss << " mv s0, sp\n";
// 生成基本块代码 // 生成基本块代码
for (const auto& bb : func->getBasicBlocks()) { for (const auto& bb : func->getBasicBlocks()) {
ss << basicBlock_gen(bb.get(), alloc); ss << basicBlock_gen(bb.get(), alloc);
} }
// 结尾:恢复 ra释放堆栈 // 结尾:恢复 ra 和 s0,释放堆栈
ss << " lw ra, 12(sp)\n"; ss << " lw ra, " << (stack_size - 4) << "(sp)\n";
ss << " addi sp, sp, 16\n"; ss << " lw s0, " << (stack_size - 8) << "(sp)\n";
ss << " addi sp, sp, " << stack_size << "\n";
ss << " ret\n"; ss << " ret\n";
return ss.str(); return ss.str();
} }
@@ -75,83 +98,175 @@ std::string RISCv32CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult&
std::stringstream ss; std::stringstream ss;
ss << bb->getName() << ":\n"; ss << bb->getName() << ":\n";
for (const auto& inst : bb->getInstructions()) { for (const auto& inst : bb->getInstructions()) {
auto riscv_insts = instruction_gen(inst.get()); auto riscv_insts = instruction_gen(inst.get(), alloc);
for (const auto& riscv_inst : riscv_insts) { for (const auto& riscv_inst : riscv_insts) {
ss << " " << riscv_inst.opcode; ss << " " << riscv_inst << "\n";
for (size_t i = 0; i < riscv_inst.operands.size(); ++i) {
if (i > 0) ss << ", ";
if (riscv_inst.operands[i].kind == Operand::Kind::Reg) {
auto it = alloc.reg_map.find(riscv_inst.operands[i].value);
if (it != alloc.reg_map.end()) {
ss << reg_to_string(it->second);
} else {
auto stack_it = alloc.stack_map.find(riscv_inst.operands[i].value);
if (stack_it != alloc.stack_map.end()) {
ss << stack_it->second << "(sp)";
} else {
ss << "%" << riscv_inst.operands[i].value->getName();
}
}
} else if (riscv_inst.operands[i].kind == Operand::Kind::Imm) {
ss << riscv_inst.operands[i].label;
} else {
ss << riscv_inst.operands[i].label;
}
}
ss << "\n";
} }
} }
return ss.str(); return ss.str();
} }
std::vector<RISCv32CodeGen::RISCv32Inst> RISCv32CodeGen::instruction_gen(Instruction* inst) { std::vector<std::string> RISCv32CodeGen::instruction_gen(Instruction* inst, const RegAllocResult& alloc) {
std::vector<RISCv32Inst> insts; std::vector<std::string> insts;
if (auto bin = dynamic_cast<BinaryInst*>(inst)) { if (auto bin = dynamic_cast<BinaryInst*>(inst)) {
std::string lhs_reg = "t0";
std::string rhs_reg = "t1";
std::string dst_reg = "t2";
// 加载 LHS
if (auto lhs_const = dynamic_cast<ConstantValue*>(bin->getLhs())) {
if (lhs_const->isInt()) {
insts.push_back("li " + lhs_reg + ", " + std::to_string(lhs_const->getInt()));
}
} else {
auto lhs_it = alloc.stack_map.find(bin->getLhs());
if (lhs_it != alloc.stack_map.end()) {
insts.push_back("lw " + lhs_reg + ", " + std::to_string(lhs_it->second) + "(s0)");
}
}
// 加载 RHS
if (auto rhs_const = dynamic_cast<ConstantValue*>(bin->getRhs())) {
if (rhs_const->isInt()) {
insts.push_back("li " + rhs_reg + ", " + std::to_string(rhs_const->getInt()));
}
} else {
auto rhs_it = alloc.stack_map.find(bin->getRhs());
if (rhs_it != alloc.stack_map.end()) {
insts.push_back("lw " + rhs_reg + ", " + std::to_string(rhs_it->second) + "(s0)");
}
}
// 执行二元操作
std::string opcode; std::string opcode;
if (bin->getKind() == BinaryInst::kAdd) opcode = "add"; if (bin->getKind() == BinaryInst::kAdd) opcode = "add";
else if (bin->getKind() == BinaryInst::kSub) opcode = "sub"; else if (bin->getKind() == BinaryInst::kSub) opcode = "sub";
else if (bin->getKind() == BinaryInst::kMul) opcode = "mul"; else if (bin->getKind() == BinaryInst::kMul) opcode = "mul";
else return insts; // 其他操作未实现 else return insts; // 未支持的操作
insts.emplace_back(opcode, std::vector<Operand>{ insts.push_back(opcode + " " + dst_reg + ", " + lhs_reg + ", " + rhs_reg);
{Operand::Kind::Reg, bin}, // 存储结果
{Operand::Kind::Reg, bin->getLhs()}, auto dst_it = alloc.stack_map.find(bin);
{Operand::Kind::Reg, bin->getRhs()} if (dst_it != alloc.stack_map.end()) {
}); insts.push_back("sw " + dst_reg + ", " + std::to_string(dst_it->second) + "(s0)");
}
} else if (auto load = dynamic_cast<LoadInst*>(inst)) { } else if (auto load = dynamic_cast<LoadInst*>(inst)) {
insts.emplace_back("lw", std::vector<Operand>{ std::string dst_reg = "t1";
{Operand::Kind::Reg, load}, // 检查是否为局部变量
{Operand::Kind::Label, load->getPointer()->getName()} auto ptr_it = alloc.stack_map.find(load->getPointer());
}); if (ptr_it != alloc.stack_map.end()) {
// 局部变量:直接从栈加载
insts.push_back("lw " + dst_reg + ", " + std::to_string(ptr_it->second) + "(s0)");
auto dst_it = alloc.stack_map.find(load);
if (dst_it != alloc.stack_map.end()) {
insts.push_back("sw " + dst_reg + ", " + std::to_string(dst_it->second) + "(s0)");
}
} else {
// 全局变量:加载地址并读取
std::string ptr_reg = "t0";
insts.push_back("la " + ptr_reg + ", " + load->getPointer()->getName());
insts.push_back("lw " + dst_reg + ", 0(" + ptr_reg + ")");
auto dst_it = alloc.stack_map.find(load);
if (dst_it != alloc.stack_map.end()) {
insts.push_back("sw " + dst_reg + ", " + std::to_string(dst_it->second) + "(s0)");
}
}
} else if (auto store = dynamic_cast<StoreInst*>(inst)) { } else if (auto store = dynamic_cast<StoreInst*>(inst)) {
insts.emplace_back("sw", std::vector<Operand>{ std::string val_reg = "t0";
{Operand::Kind::Reg, store->getValue()}, // 加载值
{Operand::Kind::Label, store->getPointer()->getName()} if (auto val_const = dynamic_cast<ConstantValue*>(store->getValue())) {
}); if (val_const->isInt()) {
insts.push_back("li " + val_reg + ", " + std::to_string(val_const->getInt()));
}
} else {
auto val_it = alloc.stack_map.find(store->getValue());
if (val_it != alloc.stack_map.end()) {
insts.push_back("lw " + val_reg + ", " + std::to_string(val_it->second) + "(s0)");
}
}
// 检查是否为局部变量
auto ptr_it = alloc.stack_map.find(store->getPointer());
if (ptr_it != alloc.stack_map.end()) {
// 局部变量:直接存储到栈
insts.push_back("sw " + val_reg + ", " + std::to_string(ptr_it->second) + "(s0)");
} else {
// 全局变量:加载地址并存储
std::string ptr_reg = "t1";
insts.push_back("la " + ptr_reg + ", " + store->getPointer()->getName());
insts.push_back("sw " + val_reg + ", 0(" + ptr_reg + ")");
}
} else if (auto ret = dynamic_cast<ReturnInst*>(inst)) {
if (ret->hasReturnValue()) {
if (auto ret_const = dynamic_cast<ConstantValue*>(ret->getReturnValue())) {
if (ret_const->isInt()) {
insts.push_back("li a0, " + std::to_string(ret_const->getInt()));
}
} else {
auto ret_it = alloc.stack_map.find(ret->getReturnValue());
if (ret_it != alloc.stack_map.end()) {
insts.push_back("lw a0, " + std::to_string(ret_it->second) + "(s0)");
}
}
}
// 栈恢复在 function_gen 中处理
} }
return insts; return insts;
} }
RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* func) {
RegAllocResult result;
int stack_offset = 0; // 从 0 开始,每槽增 4
std::set<Value*> allocated; // 跟踪已分配的变量
for (const auto& bb : func->getBasicBlocks()) {
for (const auto& inst : bb->getInstructions()) {
// 为局部变量分配栈空间
if (auto store = dynamic_cast<StoreInst*>(inst.get())) {
auto ptr = store->getPointer();
if (result.stack_map.find(ptr) == result.stack_map.end() && allocated.find(ptr) == allocated.end()) {
result.stack_map[ptr] = stack_offset;
stack_offset += 4;
allocated.insert(ptr);
}
} else if (auto bin = dynamic_cast<BinaryInst*>(inst.get())) {
// 为二元操作结果分配栈空间
if (result.stack_map.find(bin) == result.stack_map.end() && allocated.find(bin) == allocated.end()) {
result.stack_map[bin] = stack_offset;
stack_offset += 4;
allocated.insert(bin);
}
} else if (auto ret = dynamic_cast<ReturnInst*>(inst.get())) {
// 为返回值分配栈空间(如果需要)
if (ret->hasReturnValue() && !dynamic_cast<ConstantValue*>(ret->getReturnValue())) {
auto ret_val = ret->getReturnValue();
if (result.stack_map.find(ret_val) == result.stack_map.end() && allocated.find(ret_val) == allocated.end()) {
result.stack_map[ret_val] = stack_offset;
stack_offset += 4;
allocated.insert(ret_val);
}
}
}
}
}
// 为 ra 和 s0 预留空间
result.stack_size = stack_offset + 8; // ra (4) + s0 (4)
// 按 16 字节对齐
if (result.stack_size % 16 != 0) {
result.stack_size += (16 - (result.stack_size % 16));
}
return result;
}
void RISCv32CodeGen::eliminate_phi(Function* func) { void RISCv32CodeGen::eliminate_phi(Function* func) {
// TODO: 实现 phi 指令消除 // 占位符:未实现 Phi 消除
} }
std::map<Instruction*, std::set<Value*>> RISCv32CodeGen::liveness_analysis(Function* func) { std::map<Instruction*, std::set<Value*>> RISCv32CodeGen::liveness_analysis(Function* func) {
std::map<Instruction*, std::set<Value*>> live_sets; std::map<Instruction*, std::set<Value*>> live_sets;
// TODO: 实现活跃性分析 // 占位符:未实现活跃性分析
return live_sets; return live_sets;
} }
std::map<Value*, std::set<Value*>> RISCv32CodeGen::build_interference_graph( std::map<Value*, std::set<Value*>> RISCv32CodeGen::build_interference_graph(
const std::map<Instruction*, std::set<Value*>>& live_sets) { const std::map<Instruction*, std::set<Value*>>& live_sets) {
std::map<Value*, std::set<Value*>> graph; std::map<Value*, std::set<Value*>> graph;
// TODO: 实现干扰图构建 // 占位符:未实现干扰图构建
return graph; return graph;
} }
RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* func) {
RegAllocResult result;
// TODO: 实现寄存器分配
return result;
}
} // namespace sysy } // namespace sysy

View File

@@ -19,6 +19,7 @@ private:
// 物理寄存器 // 物理寄存器
enum class PhysicalReg { enum class PhysicalReg {
S0, // x8, 帧指针
T0, T1, T2, T3, T4, T5, T6, // x5-x7, x28-x31 T0, T1, T2, T3, T4, T5, T6, // x5-x7, x28-x31
A0, A1, A2, A3, A4, A5, A6, A7 // x10-x17 A0, A1, A2, A3, A4, A5, A6, A7 // x10-x17
}; };
@@ -53,7 +54,7 @@ private:
std::string module_gen(); std::string module_gen();
std::string function_gen(Function* func); std::string function_gen(Function* func);
std::string basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc); std::string basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc);
std::vector<RISCv32Inst> instruction_gen(Instruction* inst); std::vector<std::string> instruction_gen(Instruction* inst, const RegAllocResult& alloc);
RegAllocResult register_allocation(Function* func); RegAllocResult register_allocation(Function* func);
void eliminate_phi(Function* func); void eliminate_phi(Function* func);
std::map<Instruction*, std::set<Value*>> liveness_analysis(Function* func); std::map<Instruction*, std::set<Value*>> liveness_analysis(Function* func);

View File

@@ -1,12 +1,8 @@
//test add //test add
int main(){ int main(){
int a, b; int a, b;
float d;
a = 10; a = 10;
b = 2; b = 2;
int c = a; return a + b;
d = 1.1 ;
return a + b + c;
} }

View File

@@ -8,7 +8,7 @@ int main() {
if (a == b) if (a == b)
c = a + b; c = a + b;
else else
c = a * b; c = a * b + b;
return c; return c;
} }