diff --git a/src/RISCv32Backend.cpp b/src/RISCv32Backend.cpp index bc0772a..46e91cd 100644 --- a/src/RISCv32Backend.cpp +++ b/src/RISCv32Backend.cpp @@ -14,17 +14,35 @@ 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"; - case PhysicalReg::T6: return "t6"; case PhysicalReg::A0: return "a0"; - case PhysicalReg::A1: return "a1"; case PhysicalReg::A2: return "a2"; - case PhysicalReg::A3: return "a3"; case PhysicalReg::A4: return "a4"; - case PhysicalReg::A5: return "a5"; case PhysicalReg::A6: return "a6"; + 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"; + case PhysicalReg::T6: return "t6"; + case PhysicalReg::A0: return "a0"; + case PhysicalReg::A1: return "a1"; + case PhysicalReg::A2: return "a2"; + case PhysicalReg::A3: return "a3"; + case PhysicalReg::A4: return "a4"; + case PhysicalReg::A5: return "a5"; + case PhysicalReg::A6: return "a6"; case PhysicalReg::A7: return "a7"; default: return ""; } } +// 简单的临时寄存器分配器 +class TempRegAllocator { + std::vector regs = {"t0", "t1", "t2", "t3", "t4", "t5", "t6"}; + size_t current = 0; +public: + std::string get_next() { + if (current >= regs.size()) throw std::runtime_error("临时寄存器不足"); + return regs[current++]; + } + void reset() { current = 0; } +}; std::string RISCv32CodeGen::code_gen() { std::stringstream ss; @@ -34,7 +52,6 @@ std::string RISCv32CodeGen::code_gen() { std::string RISCv32CodeGen::module_gen() { std::stringstream ss; - // 生成全局变量(数据段) bool has_globals = !module->getGlobals().empty(); if (has_globals) { ss << ".data\n"; @@ -59,7 +76,6 @@ std::string RISCv32CodeGen::module_gen() { } } } - // 生成函数(文本段) if (!module->getFunctions().empty()) { ss << ".text\n"; for (const auto& func : module->getFunctions()) { @@ -71,25 +87,24 @@ std::string RISCv32CodeGen::module_gen() { std::string RISCv32CodeGen::function_gen(Function* func) { std::stringstream ss; - // 函数标签 ss << ".globl " << func->getName() << "\n"; ss << func->getName() << ":\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"; - // 生成基本块代码 + if (stack_size > 0) { + 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 和 s0,释放堆栈 - ss << " lw ra, " << (stack_size - 4) << "(sp)\n"; - ss << " lw s0, " << (stack_size - 8) << "(sp)\n"; - ss << " addi sp, sp, " << stack_size << "\n"; + if (stack_size > 0) { + 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(); } @@ -108,168 +123,249 @@ std::string RISCv32CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& std::vector RISCv32CodeGen::instruction_gen(Instruction* inst, const RegAllocResult& alloc) { std::vector insts; - if (auto bin = dynamic_cast(inst)) { + + auto load_operand = [&](Value* val, const std::string& reg) { + if (auto constant = dynamic_cast(val)) { + if (constant->isInt()) { + insts.push_back("li " + reg + ", " + std::to_string(constant->getInt())); + } else { + float f = constant->getFloat(); + uint32_t float_bits = *(uint32_t*)&f; + insts.push_back("li " + reg + ", " + std::to_string(float_bits)); + insts.push_back("fmv.w.x " + reg + ", " + reg); + } + } else if (alloc.stack_map.find(val) != alloc.stack_map.end()) { + insts.push_back("lw " + reg + ", " + std::to_string(alloc.stack_map.at(val)) + "(s0)"); + } else if (auto global = dynamic_cast(val)) { + insts.push_back("la " + reg + ", " + global->getName()); + } + }; + + if (auto alloca = dynamic_cast(inst)) { + // 栈空间已在 register_allocation 中分配 + } + else if (auto store = dynamic_cast(inst)) { + std::string val_reg = "t0"; + load_operand(store->getValue(), val_reg); + auto ptr = store->getPointer(); + if (auto alloca = dynamic_cast(ptr)) { + int offset = alloc.stack_map.at(alloca); + insts.push_back("sw " + val_reg + ", " + std::to_string(offset) + "(s0)"); + } else if (auto global = dynamic_cast(ptr)) { + std::string ptr_reg = "t1"; + insts.push_back("la " + ptr_reg + ", " + global->getName()); + insts.push_back("sw " + val_reg + ", 0(" + ptr_reg + ")"); + } + } + else if (auto load = dynamic_cast(inst)) { + std::string dst_reg = "t0"; + auto ptr = load->getPointer(); + if (auto alloca = dynamic_cast(ptr)) { + int offset = alloc.stack_map.at(alloca); + insts.push_back("lw " + dst_reg + ", " + std::to_string(offset) + "(s0)"); + } else if (auto global = dynamic_cast(ptr)) { + std::string ptr_reg = "t1"; + insts.push_back("la " + ptr_reg + ", " + global->getName()); + insts.push_back("lw " + dst_reg + ", 0(" + ptr_reg + ")"); + } + if (alloc.stack_map.find(load) != alloc.stack_map.end()) { + insts.push_back("sw " + dst_reg + ", " + std::to_string(alloc.stack_map.at(load)) + "(s0)"); + } + } + else 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 if (auto lhs_load = dynamic_cast(bin->getLhs())) { - auto ptr_it = alloc.stack_map.find(lhs_load->getPointer()); - if (ptr_it != alloc.stack_map.end()) { - insts.push_back("lw " + lhs_reg + ", " + std::to_string(ptr_it->second) + "(s0)"); - } - } 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 if (auto rhs_load = dynamic_cast(bin->getRhs())) { - auto ptr_it = alloc.stack_map.find(rhs_load->getPointer()); - if (ptr_it != alloc.stack_map.end()) { - insts.push_back("lw " + rhs_reg + ", " + std::to_string(ptr_it->second) + "(s0)"); - } - } 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)"); - } - } - // 执行二元操作 + load_operand(bin->getLhs(), lhs_reg); + load_operand(bin->getRhs(), rhs_reg); 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.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)"); + switch (bin->getKind()) { + case BinaryInst::kAdd: opcode = "add"; break; + case BinaryInst::kSub: opcode = "sub"; break; + case BinaryInst::kMul: opcode = "mul"; break; + case BinaryInst::kDiv: opcode = "div"; break; + case BinaryInst::kRem: opcode = "rem"; break; + case BinaryInst::kFAdd: opcode = "fadd.s"; break; + case BinaryInst::kFSub: opcode = "fsub.s"; break; + case BinaryInst::kFMul: opcode = "fmul.s"; break; + case BinaryInst::kFDiv: opcode = "fdiv.s"; break; + case BinaryInst::kICmpEQ: insts.push_back("seqz " + dst_reg + ", " + lhs_reg); break; + case BinaryInst::kICmpNE: insts.push_back("snez " + dst_reg + ", " + lhs_reg); break; + case BinaryInst::kICmpLT: insts.push_back("slt " + dst_reg + ", " + lhs_reg + ", " + rhs_reg); break; + case BinaryInst::kICmpGT: insts.push_back("sgt " + dst_reg + ", " + lhs_reg + ", " + rhs_reg); break; + case BinaryInst::kICmpLE: insts.push_back("sle " + dst_reg + ", " + lhs_reg + ", " + rhs_reg); break; + case BinaryInst::kICmpGE: insts.push_back("sge " + dst_reg + ", " + lhs_reg + ", " + rhs_reg); break; + case BinaryInst::kAnd: opcode = "and"; break; + case BinaryInst::kOr: opcode = "or"; break; + default: return insts; } - } else if (auto load = dynamic_cast(inst)) { + if (!opcode.empty()) { + insts.push_back(opcode + " " + dst_reg + ", " + lhs_reg + ", " + rhs_reg); + } + if (alloc.stack_map.find(bin) != alloc.stack_map.end()) { + insts.push_back("sw " + dst_reg + ", " + std::to_string(alloc.stack_map.at(bin)) + "(s0)"); + } + } + else if (auto uny = dynamic_cast(inst)) { + std::string src_reg = "t0"; 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)"); - } else { - // 全局变量:加载地址并读取 - std::string ptr_reg = "t0"; - insts.push_back("la " + ptr_reg + ", " + load->getPointer()->getName()); - insts.push_back("lw " + dst_reg + ", 0(" + ptr_reg + ")"); + load_operand(uny->getOperand(), src_reg); + switch (uny->getKind()) { + case UnaryInst::kNeg: insts.push_back("sub " + dst_reg + ", x0, " + src_reg); break; + case UnaryInst::kNot: insts.push_back("xori " + dst_reg + ", " + src_reg + ", -1"); break; + case UnaryInst::kFNeg: insts.push_back("fneg.s " + dst_reg + ", " + src_reg); break; + case UnaryInst::kFtoI: insts.push_back("fcvt.w.s " + dst_reg + ", " + src_reg); break; + case UnaryInst::kItoF: insts.push_back("fcvt.s.w " + dst_reg + ", " + src_reg); break; + case UnaryInst::kBitFtoI: insts.push_back("fmv.x.w " + dst_reg + ", " + src_reg); break; + case UnaryInst::kBitItoF: insts.push_back("fmv.w.x " + dst_reg + ", " + src_reg); break; + default: return insts; } - // 仅在需要时存储 - 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)"); + if (alloc.stack_map.find(uny) != alloc.stack_map.end()) { + insts.push_back("sw " + dst_reg + ", " + std::to_string(alloc.stack_map.at(uny)) + "(s0)"); } - } else if (auto store = dynamic_cast(inst)) { - 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)"); - } + } + else if (auto call = dynamic_cast(inst)) { + auto args = call->getArguments(); + size_t i = 0; + for (auto it = args.begin(); it != args.end() && i < 8; ++it, ++i) { + load_operand((*it)->getValue(), "a" + std::to_string(i)); } - // 检查是否为局部变量 - 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 + ")"); + insts.push_back("jal " + call->getCallee()->getName()); + if (alloc.stack_map.find(call) != alloc.stack_map.end()) { + insts.push_back("sw a0, " + std::to_string(alloc.stack_map.at(call)) + "(s0)"); } - } else if (auto ret = dynamic_cast(inst)) { + } + else if (auto condBr = dynamic_cast(inst)) { + std::string cond_reg = "t0"; + load_operand(condBr->getCondition(), cond_reg); + insts.push_back("bnez " + cond_reg + ", " + condBr->getThenBlock()->getName()); + insts.push_back("j " + condBr->getElseBlock()->getName()); + } + else if (auto br = dynamic_cast(inst)) { + insts.push_back("j " + br->getBlock()->getName()); + } + 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)"); - } - } + load_operand(ret->getReturnValue(), "a0"); } - // 栈恢复在 function_gen 中处理 + } + else if (auto la = dynamic_cast(inst)) { + std::string dst_reg = "t0"; + load_operand(la->getPointer(), dst_reg); + for (size_t i = 0; i < la->getNumIndices(); ++i) { + std::string idx_reg = "t1"; + load_operand(la->getIndex(i), idx_reg); + insts.push_back("slli " + idx_reg + ", " + idx_reg + ", 2"); + insts.push_back("add " + dst_reg + ", " + dst_reg + ", " + idx_reg); + } + if (alloc.stack_map.find(la) != alloc.stack_map.end()) { + insts.push_back("sw " + dst_reg + ", " + std::to_string(alloc.stack_map.at(la)) + "(s0)"); + } + } + else if (auto memset = dynamic_cast(inst)) { + std::string ptr_reg = "t0"; + std::string val_reg = "t1"; + std::string size_reg = "t2"; + load_operand(memset->getPointer(), ptr_reg); + load_operand(memset->getValue(), val_reg); + load_operand(memset->getSize(), size_reg); + insts.push_back("mv t3, " + ptr_reg); + insts.push_back("add t4, " + ptr_reg + ", " + size_reg); + insts.push_back("1: sw " + val_reg + ", 0(" + ptr_reg + ")"); + insts.push_back("addi " + ptr_reg + ", " + ptr_reg + ", 4"); + insts.push_back("blt " + ptr_reg + ", t4, 1b"); + } + else if (auto phi = dynamic_cast(inst)) { + // Phi 指令由 eliminate_phi 处理 } return insts; } RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* func) { RegAllocResult result; - int stack_offset = 0; // 从 0 开始,每槽增 4 - std::set allocated; // 跟踪已分配的变量 + int stack_offset = 0; + 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; + if (auto alloca = dynamic_cast(inst.get())) { + if (result.stack_map.find(alloca) == result.stack_map.end()) { + result.stack_map[alloca] = stack_offset; stack_offset += 4; - allocated.insert(ptr); } - } else if (auto load = dynamic_cast(inst.get())) { - // 为 load 结果分配栈空间(如果后续使用) - if (result.stack_map.find(load) == result.stack_map.end() && allocated.find(load) == allocated.end()) { - result.stack_map[load] = stack_offset; - stack_offset += 4; - allocated.insert(load); - } - } else if (auto bin = dynamic_cast(inst.get())) { - // 为二元操作结果分配栈空间 + } + } + } + + // 分配函数参数栈空间(入口块的 arguments) + auto entry_block = func->getEntryBlock(); + auto args = entry_block->getArguments(); + for (size_t i = 0; i < args.size(); ++i) { + if (i >= 8) { // 超过 8 个参数需要栈空间 + if (result.stack_map.find(args[i]) == result.stack_map.end()) { + result.stack_map[args[i]] = stack_offset; + stack_offset += 4; + } + } + } + + // 分配中间结果栈空间(如 BinaryInst 和 CallInst) + for (const auto& bb : func->getBasicBlocks()) { + for (const auto& inst : bb->getInstructions()) { + 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 call = dynamic_cast(inst.get())) { + if (result.stack_map.find(call) == result.stack_map.end() && allocated.find(call) == allocated.end()) { + result.stack_map[call] = stack_offset; + stack_offset += 4; + allocated.insert(call); + } } } } - // 为 ra 和 s0 预留空间 - result.stack_size = stack_offset + 8; // ra (4) + s0 (4) - // 按 16 字节对齐 + + // 检查是否需要保存 ra 和 s0 + bool needs_caller_saved = false; + for (const auto& bb : func->getBasicBlocks()) { + for (const auto& inst : bb->getInstructions()) { + if (dynamic_cast(inst.get())) { + needs_caller_saved = true; + break; + } + } + if (needs_caller_saved) break; + } + + if (needs_caller_saved || stack_offset > 0) { + stack_offset += 8; // 保存 ra 和 s0 + } + + result.stack_size = stack_offset; if (result.stack_size % 16 != 0) { - result.stack_size += (16 - (result.stack_size % 16)); + result.stack_size += (16 - result.stack_size % 16); } return result; } void RISCv32CodeGen::eliminate_phi(Function* func) { - // 占位符:未实现 Phi 消除 + // Placeholder: Phi elimination requires inserting moves at predecessor blocks } std::map> RISCv32CodeGen::liveness_analysis(Function* func) { std::map> live_sets; - // 占位符:未实现活跃性分析 + // Placeholder: Implement liveness analysis return live_sets; } std::map> RISCv32CodeGen::build_interference_graph( const std::map>& live_sets) { std::map> graph; - // 占位符:未实现干扰图构建 + // Placeholder: Implement interference graph return graph; } diff --git a/test/10_test.sy b/test/10_test.sy index f719269..fb3dbd7 100644 --- a/test/10_test.sy +++ b/test/10_test.sy @@ -6,9 +6,9 @@ int main() { int c; if (a == b) - c = a + b; + c = b - a + 20; // 21 <- this else - c = a * b + b; + c = a * b + b + b + 10; // 16 return c; } diff --git a/test/11_add2.sy b/test/11_add2.sy index c783a32..7a662d7 100644 --- a/test/11_add2.sy +++ b/test/11_add2.sy @@ -7,7 +7,7 @@ int mul(int x, int y) { int main(){ int a, b; a = 10; - b = 0; - a = mul(a, b); - return a + b; + b = 3; + a = mul(a, b); //60 + return a + b; //66 }