diff --git a/src/RISCv64Backend.cpp b/src/RISCv64Backend.cpp index 3bbc148..913f7ab 100644 --- a/src/RISCv64Backend.cpp +++ b/src/RISCv64Backend.cpp @@ -635,6 +635,14 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al } } else { std::string ptr_reg = get_preg_or_temp(ptr_node->result_vreg); + + // [与STORE逻辑类似的修复] 如果是从一个全局地址加载,先用la加载地址 + if (ptr_node->kind == DAGNode::CONSTANT) { + if (auto global = dynamic_cast(ptr_node->value)) { + ss_inst << "la " << ptr_reg << ", " << global->getName() << "\n\t"; + } + } + ss_inst << "lw " << dest_reg << ", 0(" << ptr_reg << ")"; } break; @@ -660,18 +668,30 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al // 如果 STORE 的目标是浮点数,这里逻辑需要调整 } } else if (auto global = dynamic_cast(val_node->value)) { - // 如果是存储全局变量的地址 + // 如果要存储的值是另一个全局变量的地址 ss_inst << "la " << src_reg << ", " << global->getName() << "\n\t"; } } + // [本次修复] 处理目标地址,并生成最终的存储指令 if (ptr_node->kind == DAGNode::ALLOCA_ADDR) { + // 情况1: 存储到栈上的局部变量 if (auto alloca_inst = dynamic_cast(ptr_node->value)) { int offset = alloc.stack_map.at(alloca_inst); ss_inst << "sw " << src_reg << ", " << offset << "(s0)"; } } else { + // 情况2: 存储到指针指向的地址 (可能是全局变量或已计算的地址) std::string ptr_reg = get_preg_or_temp(ptr_node->result_vreg); + + // 如果指针本身是一个全局变量的地址,需要先用 la 加载它 + if (ptr_node->kind == DAGNode::CONSTANT) { + if (auto global = dynamic_cast(ptr_node->value)) { + ss_inst << "la " << ptr_reg << ", " << global->getName() << "\n\t"; + } + } + + // 生成最终的存储指令 ss_inst << "sw " << src_reg << ", 0(" << ptr_reg << ")"; } break; @@ -712,10 +732,12 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al std::string lhs_reg = get_preg_or_temp(lhs_node->result_vreg); std::string rhs_reg = get_preg_or_temp(rhs_node->result_vreg); - // [V2 特性] 在生成二元运算指令前,检查操作数是否为常数,并按需加载 + // [V2 特性] & [上次修复] 在生成二元运算指令前,检查操作数是否为常数(立即数或全局地址),并按需加载 if (lhs_node->kind == DAGNode::CONSTANT) { if (auto c = dynamic_cast(lhs_node->value)) { ss_inst << "li " << lhs_reg << ", " << c->getInt() << "\n\t"; + } else if (auto g = dynamic_cast(lhs_node->value)) { + ss_inst << "la " << lhs_reg << ", " << g->getName() << "\n\t"; } } if (rhs_node->kind == DAGNode::CONSTANT) { @@ -728,6 +750,8 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al } // 否则,正常加载 ss_inst << "li " << rhs_reg << ", " << c->getInt() << "\n\t"; + } else if (auto g = dynamic_cast(rhs_node->value)) { + ss_inst << "la " << rhs_reg << ", " << g->getName() << "\n\t"; } } @@ -853,10 +877,12 @@ void RISCv64CodeGen::select_instructions(DAGNode* node, const RegAllocResult& al if (!node->operands.empty() && node->operands[0]) { DAGNode* ret_val_node = node->operands[0]; - // [V2 特性] 如果返回值是常量,直接加载到 a0 + // [V2 特性] & [上次修复] 如果返回值是常量(立即数或全局地址),直接加载到 a0 if (ret_val_node->kind == DAGNode::CONSTANT) { if (auto c = dynamic_cast(ret_val_node->value)) { ss_inst << "li a0, " << c->getInt() << "\n"; + } else if (auto g = dynamic_cast(ret_val_node->value)) { + ss_inst << "la a0, " << g->getName() << "\n"; } } else { std::string return_val_reg = get_preg_or_temp(ret_val_node->result_vreg);