diff --git a/src/backend/RISCv64/RISCv64Backend.cpp b/src/backend/RISCv64/RISCv64Backend.cpp index c32af0c..2a99b72 100644 --- a/src/backend/RISCv64/RISCv64Backend.cpp +++ b/src/backend/RISCv64/RISCv64Backend.cpp @@ -16,7 +16,7 @@ std::string RISCv64CodeGen::code_gen() { std::string RISCv64CodeGen::module_gen() { std::stringstream ss; - // --- [新逻辑] 步骤1:将全局变量分为.data和.bss两组 --- + // --- 步骤1:将全局变量(GlobalValue)分为.data和.bss两组 --- std::vector data_globals; std::vector bss_globals; @@ -26,7 +26,6 @@ std::string RISCv64CodeGen::module_gen() { // 判断是否为大型零初始化数组,以便放入.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) { @@ -42,33 +41,56 @@ std::string RISCv64CodeGen::module_gen() { } } - // --- [新逻辑] 步骤2:生成 .bss 段的代码 --- + // --- 步骤2:生成 .bss 段的代码 (这部分不变) --- if (!bss_globals.empty()) { - ss << ".bss\n"; // 切换到 .bss 段 + ss << ".bss\n"; for (GlobalValue* global : bss_globals) { - // 获取数组总大小(元素个数 * 元素大小) - // 在SysY中,我们假设元素都是4字节(int或float) unsigned count = global->getInitValues().getNumbers()[0]; - unsigned total_size = count * 4; + unsigned total_size = count * 4; // 假设元素都是4字节 - ss << " .align 3\n"; // 8字节对齐 (2^3) + 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"; - // 使用 .space 指令来预留指定大小的零填充空间 ss << " .space " << total_size << "\n"; } } - // --- [旧逻辑保留] 步骤3:生成 .data 段的代码 --- - if (!data_globals.empty()) { - ss << ".data\n"; // 切换到 .data 段 + // --- [修改] 步骤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"; 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"; + } + } + } + } + } + + // b. [新增] 再处理全局常量 (ConstantVariable) + for (const auto& const_ptr : module->getConsts()) { + ConstantVariable* cnst = const_ptr.get(); + ss << ".globl " << cnst->getName() << "\n"; + ss << cnst->getName() << ":\n"; + const auto& init_values = cnst->getInitValues(); + // 这部分逻辑和处理 GlobalValue 完全相同 for (size_t i = 0; i < init_values.getValues().size(); ++i) { auto val = init_values.getValues()[i]; auto count = init_values.getNumbers()[i]; diff --git a/src/backend/RISCv64/RISCv64ISel.cpp b/src/backend/RISCv64/RISCv64ISel.cpp index 01e9bb6..a6efc09 100644 --- a/src/backend/RISCv64/RISCv64ISel.cpp +++ b/src/backend/RISCv64/RISCv64ISel.cpp @@ -862,6 +862,11 @@ void RISCv64ISel::selectNode(DAGNode* node) { la_instr->addOperand(std::make_unique(current_addr_vreg)); la_instr->addOperand(std::make_unique(global_base->getName())); CurMBB->addInstruction(std::move(la_instr)); + } else if (auto const_global_base = dynamic_cast(base_ptr_node->value)) { + auto la_instr = std::make_unique(RVOpcodes::LA); + la_instr->addOperand(std::make_unique(current_addr_vreg)); + la_instr->addOperand(std::make_unique(const_global_base->getName())); + CurMBB->addInstruction(std::move(la_instr)); } else { auto base_vreg = getVReg(base_ptr_node->value); auto mv = std::make_unique(RVOpcodes::MV);