diff --git a/src/RISCv32Backend.cpp b/src/RISCv32Backend.cpp index 41df201..99ac019 100644 --- a/src/RISCv32Backend.cpp +++ b/src/RISCv32Backend.cpp @@ -13,6 +13,7 @@ const std::vector RISCv32CodeGen::allocable_regs = std::string RISCv32CodeGen::reg_to_string(PhysicalReg reg) { switch (reg) { + case PhysicalReg::S0: return "s0"; case PhysicalReg::T0: return "t0"; case PhysicalReg::T1: return "t1"; case PhysicalReg::T2: return "t2"; case PhysicalReg::T3: return "t3"; 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::stringstream ss; - ss << ".text\n"; ss << module_gen(); return ss.str(); } @@ -35,16 +35,36 @@ std::string RISCv32CodeGen::code_gen() { std::string RISCv32CodeGen::module_gen() { std::stringstream ss; // 生成全局变量(数据段) - for (const auto& global : module->getGlobals()) { + bool has_globals = !module->getGlobals().empty(); + if (has_globals) { ss << ".data\n"; - ss << ".globl " << global->getName() << "\n"; - ss << global->getName() << ":\n"; - ss << " .word 0\n"; // 假设初始化为0 + for (const auto& global : module->getGlobals()) { + ss << ".globl " << global->getName() << "\n"; + 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(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"; - for (const auto& func : module->getFunctions()) { - ss << function_gen(func.second.get()); + if (!module->getFunctions().empty()) { + ss << ".text\n"; + for (const auto& func : module->getFunctions()) { + ss << function_gen(func.second.get()); + } } return ss.str(); } @@ -54,19 +74,22 @@ std::string RISCv32CodeGen::function_gen(Function* func) { // 函数标签 ss << ".globl " << 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); + // 序言:分配堆栈,保存 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()) { ss << basicBlock_gen(bb.get(), alloc); } - // 结尾:恢复 ra,释放堆栈 - ss << " lw ra, 12(sp)\n"; - ss << " addi sp, sp, 16\n"; + // 结尾:恢复 ra 和 s0,释放堆栈 + ss << " lw ra, " << (stack_size - 4) << "(sp)\n"; + ss << " lw s0, " << (stack_size - 8) << "(sp)\n"; + ss << " addi sp, sp, " << stack_size << "\n"; ss << " ret\n"; return ss.str(); } @@ -75,83 +98,175 @@ std::string RISCv32CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& std::stringstream ss; ss << bb->getName() << ":\n"; 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) { - ss << " " << riscv_inst.opcode; - 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"; + ss << " " << riscv_inst << "\n"; } } return ss.str(); } -std::vector RISCv32CodeGen::instruction_gen(Instruction* inst) { - std::vector insts; +std::vector RISCv32CodeGen::instruction_gen(Instruction* inst, const RegAllocResult& alloc) { + std::vector insts; if (auto bin = dynamic_cast(inst)) { + std::string lhs_reg = "t0"; + std::string rhs_reg = "t1"; + std::string dst_reg = "t2"; + // 加载 LHS + if (auto lhs_const = dynamic_cast(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(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; if (bin->getKind() == BinaryInst::kAdd) opcode = "add"; else if (bin->getKind() == BinaryInst::kSub) opcode = "sub"; else if (bin->getKind() == BinaryInst::kMul) opcode = "mul"; - else return insts; // 其他操作未实现 - insts.emplace_back(opcode, std::vector{ - {Operand::Kind::Reg, bin}, - {Operand::Kind::Reg, bin->getLhs()}, - {Operand::Kind::Reg, bin->getRhs()} - }); + else return insts; // 未支持的操作 + insts.push_back(opcode + " " + dst_reg + ", " + lhs_reg + ", " + rhs_reg); + // 存储结果 + auto dst_it = alloc.stack_map.find(bin); + 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(inst)) { - insts.emplace_back("lw", std::vector{ - {Operand::Kind::Reg, load}, - {Operand::Kind::Label, load->getPointer()->getName()} - }); + std::string dst_reg = "t1"; + // 检查是否为局部变量 + 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(inst)) { - insts.emplace_back("sw", std::vector{ - {Operand::Kind::Reg, store->getValue()}, - {Operand::Kind::Label, store->getPointer()->getName()} - }); + std::string val_reg = "t0"; + // 加载值 + if (auto val_const = dynamic_cast(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(inst)) { + if (ret->hasReturnValue()) { + if (auto ret_const = dynamic_cast(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; } +RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* func) { + RegAllocResult result; + int stack_offset = 0; // 从 0 开始,每槽增 4 + std::set allocated; // 跟踪已分配的变量 + for (const auto& bb : func->getBasicBlocks()) { + for (const auto& inst : bb->getInstructions()) { + // 为局部变量分配栈空间 + if (auto store = dynamic_cast(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(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(inst.get())) { + // 为返回值分配栈空间(如果需要) + if (ret->hasReturnValue() && !dynamic_cast(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) { - // TODO: 实现 phi 指令消除 + // 占位符:未实现 Phi 消除 } std::map> RISCv32CodeGen::liveness_analysis(Function* func) { std::map> live_sets; - // TODO: 实现活跃性分析 + // 占位符:未实现活跃性分析 return live_sets; } std::map> RISCv32CodeGen::build_interference_graph( const std::map>& live_sets) { std::map> graph; - // TODO: 实现干扰图构建 + // 占位符:未实现干扰图构建 return graph; } -RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* func) { - RegAllocResult result; - // TODO: 实现寄存器分配 - return result; -} - } // namespace sysy \ No newline at end of file diff --git a/src/RISCv32Backend.h b/src/RISCv32Backend.h index d5fa325..7e1239c 100644 --- a/src/RISCv32Backend.h +++ b/src/RISCv32Backend.h @@ -19,6 +19,7 @@ private: // 物理寄存器 enum class PhysicalReg { + S0, // x8, 帧指针 T0, T1, T2, T3, T4, T5, T6, // x5-x7, x28-x31 A0, A1, A2, A3, A4, A5, A6, A7 // x10-x17 }; @@ -53,7 +54,7 @@ private: std::string module_gen(); std::string function_gen(Function* func); std::string basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc); - std::vector instruction_gen(Instruction* inst); + std::vector instruction_gen(Instruction* inst, const RegAllocResult& alloc); RegAllocResult register_allocation(Function* func); void eliminate_phi(Function* func); std::map> liveness_analysis(Function* func); diff --git a/test/01_add.sy b/test/01_add.sy index fc6c9be..f773ad9 100644 --- a/test/01_add.sy +++ b/test/01_add.sy @@ -1,12 +1,8 @@ //test add - int main(){ int a, b; - float d; a = 10; b = 2; - int c = a; - d = 1.1 ; - return a + b + c; + return a + b; } diff --git a/test/10_test.sy b/test/10_test.sy index 05dab29..f719269 100644 --- a/test/10_test.sy +++ b/test/10_test.sy @@ -8,7 +8,7 @@ int main() { if (a == b) c = a + b; else - c = a * b; + c = a * b + b; return c; }