From 429e47777649ea4c99770d304e48246c2ed82df4 Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Mon, 28 Jul 2025 17:29:18 +0800 Subject: [PATCH] =?UTF-8?q?[backend]=E5=BC=95=E5=85=A5=E4=BA=86=E5=AF=B9.b?= =?UTF-8?q?ss=E5=92=8C.data=E6=AE=B5=E7=9A=84=E5=8C=BA=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/RISCv64Backend.cpp | 56 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/src/RISCv64Backend.cpp b/src/RISCv64Backend.cpp index 4ee03cc..453c026 100644 --- a/src/RISCv64Backend.cpp +++ b/src/RISCv64Backend.cpp @@ -16,13 +16,59 @@ std::string RISCv64CodeGen::code_gen() { std::string RISCv64CodeGen::module_gen() { std::stringstream ss; - // 1. 处理全局变量 (.data段) - if (!module->getGlobals().empty()) { - ss << ".data\n"; - for (const auto& global : module->getGlobals()) { + // --- [新逻辑] 步骤1:将全局变量分为.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; + // 规则:初始化列表只有一项,且该项是值为0的整数,且数量大于一个阈值(例如16) + 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"; // 切换到 .bss 段 + for (GlobalValue* global : bss_globals) { + // 获取数组总大小(元素个数 * 元素大小) + // 在SysY中,我们假设元素都是4字节(int或float) + unsigned count = global->getInitValues().getNumbers()[0]; + unsigned total_size = count * 4; + + ss << " .align 3\n"; // 8字节对齐 (2^3) + ss << ".globl " << global->getName() << "\n"; + ss << ".type " << global->getName() << ", @object\n"; + ss << ".size " << global->getName() << ", " << total_size << "\n"; + ss << global->getName() << ":\n"; + // 使用 .space 指令来预留指定大小的零填充空间 + ss << " .space " << total_size << "\n"; + } + } + + // --- [旧逻辑保留] 步骤3:生成 .data 段的代码 --- + if (!data_globals.empty()) { + ss << ".data\n"; // 切换到 .data 段 + for (GlobalValue* global : data_globals) { 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]; @@ -41,7 +87,7 @@ std::string RISCv64CodeGen::module_gen() { } } - // 2. 处理函数 (.text段) + // --- 处理函数 (.text段) 的逻辑保持不变 --- if (!module->getFunctions().empty()) { ss << ".text\n"; for (const auto& func_pair : module->getFunctions()) {