#include "RISCv64Backend.h" #include "RISCv64ISel.h" #include "RISCv64RegAlloc.h" #include "RISCv64AsmPrinter.h" #include "RISCv64Passes.h" #include namespace sysy { // 顶层入口 std::string RISCv64CodeGen::code_gen() { return module_gen(); } void printInitializer(std::stringstream& ss, const ValueCounter& init_values) { 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"; } } } } } std::string RISCv64CodeGen::module_gen() { std::stringstream ss; // --- 步骤1:将全局变量(GlobalValue)分为.data和.bss两组 --- std::vector data_globals; std::vector bss_globals; for (const auto& global_ptr : module->getGlobals()) { GlobalValue* global = global_ptr.get(); const auto& init_values = global->getInitValues(); // 判断是否为大型零初始化数组,以便放入.bss段 bool is_large_zero_array = false; if (init_values.getValues().size() == 1) { if (auto const_val = dynamic_cast(init_values.getValues()[0])) { if (const_val->isInt() && const_val->getInt() == 0 && init_values.getNumbers()[0] > 16) { is_large_zero_array = true; } } } if (is_large_zero_array) { bss_globals.push_back(global); } else { data_globals.push_back(global); } } // --- 步骤2:生成 .bss 段的代码 (这部分不变) --- if (!bss_globals.empty()) { ss << ".bss\n"; for (GlobalValue* global : bss_globals) { unsigned count = global->getInitValues().getNumbers()[0]; unsigned total_size = count * 4; // 假设元素都是4字节 ss << " .align 3\n"; ss << ".globl " << global->getName() << "\n"; ss << ".type " << global->getName() << ", @object\n"; ss << ".size " << global->getName() << ", " << total_size << "\n"; ss << global->getName() << ":\n"; ss << " .space " << total_size << "\n"; } } // --- [修改] 步骤3:生成 .data 段的代码 --- // 我们需要检查 data_globals 和 常量列表是否都为空 if (!data_globals.empty() || !module->getConsts().empty()) { ss << ".data\n"; // a. 先处理普通的全局变量 (GlobalValue) for (GlobalValue* global : data_globals) { ss << ".globl " << global->getName() << "\n"; ss << global->getName() << ":\n"; printInitializer(ss, global->getInitValues()); } // b. [新增] 再处理全局常量 (ConstantVariable) for (const auto& const_ptr : module->getConsts()) { ConstantVariable* cnst = const_ptr.get(); ss << ".globl " << cnst->getName() << "\n"; ss << cnst->getName() << ":\n"; printInitializer(ss, cnst->getInitValues()); } } // --- 处理函数 (.text段) 的逻辑保持不变 --- if (!module->getFunctions().empty()) { ss << ".text\n"; for (const auto& func_pair : module->getFunctions()) { if (func_pair.second.get()) { ss << function_gen(func_pair.second.get()); } } } return ss.str(); } std::string RISCv64CodeGen::function_gen(Function* func) { // === 完整的后端处理流水线 === // 阶段 1: 指令选择 (sysy::IR -> LLIR with virtual registers) RISCv64ISel isel; std::unique_ptr mfunc = isel.runOnFunction(func); // 第一次调试打印输出 std::stringstream ss1; RISCv64AsmPrinter printer1(mfunc.get()); printer1.run(ss1, true); // 阶段 2: 指令调度 (Instruction Scheduling) PreRA_Scheduler scheduler; scheduler.runOnMachineFunction(mfunc.get()); // 阶段 3: 物理寄存器分配 (Register Allocation) RISCv64RegAlloc reg_alloc(mfunc.get()); reg_alloc.run(); // 阶段 3.1: 处理被调用者保存寄存器 CalleeSavedHandler callee_handler; callee_handler.runOnMachineFunction(mfunc.get()); // 阶段 4: 窥孔优化 (Peephole Optimization) PeepholeOptimizer peephole; peephole.runOnMachineFunction(mfunc.get()); // 阶段 5: 局部指令调度 (Local Scheduling) PostRA_Scheduler local_scheduler; local_scheduler.runOnMachineFunction(mfunc.get()); // 阶段 3.2: 插入序言和尾声 PrologueEpilogueInsertionPass pei_pass; pei_pass.runOnMachineFunction(mfunc.get()); // 阶段 3.3: 清理产生的大立即数 LegalizeImmediatesPass legalizer; legalizer.runOnMachineFunction(mfunc.get()); // 阶段 6: 代码发射 (Code Emission) std::stringstream ss; RISCv64AsmPrinter printer(mfunc.get()); printer.run(ss); if (DEBUG) ss << "\n" << ss1.str(); // 将指令选择阶段的结果也包含在最终输出中 return ss.str(); } } // namespace sysy